Add a WAIT_FOR_GPU_COMPLETION option

Change-Id: I18d526120651676109200bfd5da87cafcd7e3d13
diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h
deleted file mode 100644
index fc29f7ac1..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 <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
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 @@
     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 <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);
 
@@ -263,6 +266,14 @@
 
 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 @@
     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 @@
 
     void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
 
+    void fence();
+
 private:
     friend class RenderThread;