Loading libs/hwui/Fence.hdeleted 100644 → 0 +0 −113 Original line number Diff line number Diff line /* * 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, nullptr); } 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 libs/hwui/OpenGLRenderer.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" #include "GammaFontRenderer.h" #include "Patch.h" #include "PathTessellator.h" Loading Loading @@ -506,7 +505,7 @@ void OpenGLRenderer::flushLayerUpdates() { updateLayers(); flushLayers(); // Wait for all the layer updates to be executed AutoFence fence; glFinish(); } void OpenGLRenderer::markLayersAsBuildLayers() { Loading libs/hwui/renderthread/EglManager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ #include <cutils/log.h> #include <cutils/properties.h> #include <EGL/eglext.h> #define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions" #define GLES_VERSION 2 #define WAIT_FOR_GPU_COMPLETION 0 // Android-specific addition that is used to show when frames began in systrace EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); Loading Loading @@ -260,6 +263,14 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { bool EglManager::swapBuffers(EGLSurface surface) { mInFrame = false; #if WAIT_FOR_GPU_COMPLETION { ATRACE_NAME("Finishing GPU work"); fence(); } #endif eglSwapBuffers(mEglDisplay, surface); EGLint err = eglGetError(); if (CC_LIKELY(err == EGL_SUCCESS)) { Loading @@ -278,6 +289,13 @@ bool EglManager::swapBuffers(EGLSurface surface) { return false; } void EglManager::fence() { EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL); eglClientWaitSyncKHR(mEglDisplay, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); eglDestroySyncKHR(mEglDisplay, fence); } void EglManager::cancelFrame() { mInFrame = false; } Loading libs/hwui/renderthread/EglManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ public: void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); void fence(); private: friend class RenderThread; Loading Loading
libs/hwui/Fence.hdeleted 100644 → 0 +0 −113 Original line number Diff line number Diff line /* * 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, nullptr); } 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
libs/hwui/OpenGLRenderer.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" #include "GammaFontRenderer.h" #include "Patch.h" #include "PathTessellator.h" Loading Loading @@ -506,7 +505,7 @@ void OpenGLRenderer::flushLayerUpdates() { updateLayers(); flushLayers(); // Wait for all the layer updates to be executed AutoFence fence; glFinish(); } void OpenGLRenderer::markLayersAsBuildLayers() { Loading
libs/hwui/renderthread/EglManager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ #include <cutils/log.h> #include <cutils/properties.h> #include <EGL/eglext.h> #define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions" #define GLES_VERSION 2 #define WAIT_FOR_GPU_COMPLETION 0 // Android-specific addition that is used to show when frames began in systrace EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); Loading Loading @@ -260,6 +263,14 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { bool EglManager::swapBuffers(EGLSurface surface) { mInFrame = false; #if WAIT_FOR_GPU_COMPLETION { ATRACE_NAME("Finishing GPU work"); fence(); } #endif eglSwapBuffers(mEglDisplay, surface); EGLint err = eglGetError(); if (CC_LIKELY(err == EGL_SUCCESS)) { Loading @@ -278,6 +289,13 @@ bool EglManager::swapBuffers(EGLSurface surface) { return false; } void EglManager::fence() { EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL); eglClientWaitSyncKHR(mEglDisplay, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); eglDestroySyncKHR(mEglDisplay, fence); } void EglManager::cancelFrame() { mInFrame = false; } Loading
libs/hwui/renderthread/EglManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ public: void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); void fence(); private: friend class RenderThread; Loading