diff options
author | Romain Guy <romainguy@google.com> | 2013-06-12 15:31:28 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-06-12 15:31:28 -0700 |
commit | 405436021da156fbe3c5d4de48bdefa564cf7fc0 (patch) | |
tree | 339d70e2c2e90f87a5c303e7167fe9db0508ed64 /libs/hwui | |
parent | 97f41383eb2bb098767ca153e470009fea810540 (diff) | |
download | frameworks_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.h | 113 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 1 |
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); |