summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-06-12 15:31:28 -0700
committerRomain Guy <romainguy@google.com>2013-06-12 15:31:28 -0700
commit405436021da156fbe3c5d4de48bdefa564cf7fc0 (patch)
tree339d70e2c2e90f87a5c303e7167fe9db0508ed64 /libs/hwui
parent97f41383eb2bb098767ca153e470009fea810540 (diff)
downloadframeworks_base-405436021da156fbe3c5d4de48bdefa564cf7fc0.zip
frameworks_base-405436021da156fbe3c5d4de48bdefa564cf7fc0.tar.gz
frameworks_base-405436021da156fbe3c5d4de48bdefa564cf7fc0.tar.bz2
Restore buildLayer()'s old behavior; it's synchronous again
Bug #9193833 Change-Id: I4ee07e65c0a8967f0b55da030ecaad6dfc46136f
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/Fence.h113
-rw-r--r--libs/hwui/OpenGLRenderer.cpp14
-rw-r--r--libs/hwui/OpenGLRenderer.h1
3 files changed, 128 insertions, 0 deletions
diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h
new file mode 100644
index 0000000..f175e98
--- /dev/null
+++ b/libs/hwui/Fence.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_FENCE_H
+#define ANDROID_HWUI_FENCE_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Creating a Fence instance inserts a new sync fence in the OpenGL
+ * commands stream. The caller can then wait for the fence to be signaled
+ * by calling the wait method.
+ */
+class Fence {
+public:
+ enum {
+ /**
+ * Default timeout in nano-seconds for wait()
+ */
+ kDefaultTimeout = 1000000000
+ };
+
+ /**
+ * Inserts a new sync fence in the OpenGL commands stream.
+ */
+ Fence() {
+ mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (mDisplay != EGL_NO_DISPLAY) {
+ mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ } else {
+ mFence = EGL_NO_SYNC_KHR;
+ }
+ }
+
+ /**
+ * Destroys the fence. Any caller waiting on the fence will be
+ * signaled immediately.
+ */
+ ~Fence() {
+ if (mFence != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(mDisplay, mFence);
+ }
+ }
+
+ /**
+ * Blocks the calling thread until this fence is signaled, or until
+ * <timeout> nanoseconds have passed.
+ *
+ * Returns true if waiting for the fence was successful, false if
+ * a timeout or an error occurred.
+ */
+ bool wait(EGLTimeKHR timeout = kDefaultTimeout) {
+ EGLint waitStatus = eglClientWaitSyncKHR(mDisplay, mFence,
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, timeout);
+ if (waitStatus == EGL_FALSE) {
+ ALOGW("Failed to wait for the fence %#x", eglGetError());
+ }
+ return waitStatus == EGL_CONDITION_SATISFIED_KHR;
+ }
+
+private:
+ EGLDisplay mDisplay;
+ EGLSyncKHR mFence;
+
+}; // class Fence
+
+/**
+ * An AutoFence creates a Fence instance and waits for the fence
+ * to be signaled when the AutoFence is destroyed. This is useful
+ * to automatically wait for a series of OpenGL commands to be
+ * executed. For example:
+ *
+ * void drawAndWait() {
+ * glDrawElements();
+ * AutoFence fence;
+ * }
+ */
+class AutoFence {
+public:
+ AutoFence(EGLTimeKHR timeout = Fence::kDefaultTimeout): mTimeout(timeout) {
+ }
+
+ ~AutoFence() {
+ mFence.wait(mTimeout);
+ }
+
+private:
+ EGLTimeKHR mTimeout;
+ Fence mFence;
+
+}; // class AutoFence
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_FENCE_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d95a62c..fa1eb97 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -33,6 +33,7 @@
#include "OpenGLRenderer.h"
#include "DeferredDisplayList.h"
#include "DisplayListRenderer.h"
+#include "Fence.h"
#include "PathTessellator.h"
#include "Properties.h"
#include "Vector.h"
@@ -552,6 +553,8 @@ void OpenGLRenderer::countOverdraw() {
bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
if (layer->deferredUpdateScheduled && layer->renderer &&
layer->displayList && layer->displayList->isRenderable()) {
+ ATRACE_CALL();
+
Rect& dirty = layer->dirtyRect;
if (inFrame) {
@@ -619,8 +622,11 @@ void OpenGLRenderer::flushLayers() {
sprintf(layerName, "Layer #%d", i);
startMark(layerName);
+ ATRACE_BEGIN("flushLayer");
Layer* layer = mLayerUpdates.itemAt(i);
layer->flush();
+ ATRACE_END();
+
mCaches.resourceCache.decrementRefcount(layer);
endMark();
@@ -661,6 +667,14 @@ void OpenGLRenderer::clearLayerUpdates() {
}
}
+void OpenGLRenderer::flushLayerUpdates() {
+ syncState();
+ updateLayers();
+ flushLayers();
+ // Wait for all the layer updates to be executed
+ AutoFence fence;
+}
+
///////////////////////////////////////////////////////////////////////////////
// State management
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index ce4ce42..1ab493c 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -208,6 +208,7 @@ public:
ANDROID_API void pushLayerUpdate(Layer* layer);
ANDROID_API void clearLayerUpdates();
+ ANDROID_API void flushLayerUpdates();
ANDROID_API int getSaveCount() const;
virtual int save(int flags);