From 5515637540bedd8fc9a1a6e46a4b512dd45520a5 Mon Sep 17 00:00:00 2001 From: John Reck Date: Wed, 21 Jan 2015 07:46:37 -0800 Subject: Add a WAIT_FOR_GPU_COMPLETION option Change-Id: I18d526120651676109200bfd5da87cafcd7e3d13 --- libs/hwui/Fence.h | 113 ---------------------------------- libs/hwui/OpenGLRenderer.cpp | 3 +- libs/hwui/renderthread/EglManager.cpp | 18 ++++++ libs/hwui/renderthread/EglManager.h | 2 + 4 files changed, 21 insertions(+), 115 deletions(-) delete mode 100644 libs/hwui/Fence.h (limited to 'libs') diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h deleted file mode 100644 index fc29f7a..0000000 --- a/libs/hwui/Fence.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 -#include - -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 - * 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 42b246c..76525e0 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -20,7 +20,6 @@ #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" -#include "Fence.h" #include "GammaFontRenderer.h" #include "Patch.h" #include "PathTessellator.h" @@ -563,7 +562,7 @@ void OpenGLRenderer::flushLayerUpdates() { updateLayers(); flushLayers(); // Wait for all the layer updates to be executed - AutoFence fence; + glFinish(); } void OpenGLRenderer::markLayersAsBuildLayers() { diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index c4feb41..28aa938 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -22,10 +22,13 @@ #include #include +#include #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); @@ -263,6 +266,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)) { @@ -281,6 +292,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; } diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index e12db3a..b1a18a9 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -55,6 +55,8 @@ public: void setTextureAtlas(const sp& buffer, int64_t* map, size_t mapSize); + void fence(); + private: friend class RenderThread; -- cgit v1.1