OSDN Git Service

Add eglSwapBuffersWithDamageKHR support
authorJohn Reck <jreck@google.com>
Fri, 8 May 2015 17:04:36 +0000 (10:04 -0700)
committerJohn Reck <jreck@google.com>
Fri, 8 May 2015 17:48:57 +0000 (10:48 -0700)
BUG: 20761426
Disabled temporarily

Change-Id: I0b6b6f0eebab886145e13fa35aefe76826965cf5

libs/hwui/Properties.cpp
libs/hwui/Properties.h
libs/hwui/renderthread/CanvasContext.cpp
libs/hwui/renderthread/CanvasContext.h
libs/hwui/renderthread/EglManager.cpp
libs/hwui/renderthread/EglManager.h

index fd32b6f..723a177 100644 (file)
@@ -28,6 +28,8 @@ bool Properties::drawReorderDisabled = false;
 bool Properties::debugLayersUpdates = false;
 bool Properties::debugOverdraw = false;
 bool Properties::showDirtyRegions = false;
+bool Properties::skipEmptyFrames = true;
+bool Properties::swapBuffersWithDamage = false;
 
 DebugLevel Properties::debugLevel = kDebugDisabled;
 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
@@ -101,6 +103,9 @@ bool Properties::load() {
         debugLevel = (DebugLevel) atoi(property);
     }
 
+    skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true);
+    swapBuffersWithDamage = property_get_bool(PROPERTY_SWAP_WITH_DAMAGE, false);
+
     return (prevDebugLayersUpdates != debugLayersUpdates)
             || (prevDebugOverdraw != debugOverdraw)
             || (prevDebugStencilClip != debugStencilClip);
index 46fa940..cb5560f 100644 (file)
@@ -158,6 +158,21 @@ enum DebugLevel {
  */
 #define PROPERTY_DISABLE_DRAW_REORDER "debug.hwui.disable_draw_reorder"
 
+/**
+ * Setting this property will enable or disable the dropping of frames with
+ * empty damage. Default is "true".
+ */
+#define PROPERTY_SKIP_EMPTY_DAMAGE "debug.hwui.skip_empty_damage"
+
+/**
+ * Setting this property will enable usage of EGL_KHR_swap_buffers_with_damage
+ * See: https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_swap_buffers_with_damage.txt
+ * Default is "false" temporarily
+ * TODO: Change to "true", make sure to remove the log in EglManager::swapBuffers
+ * before changing this to default to true!
+ */
+#define PROPERTY_SWAP_WITH_DAMAGE "debug.hwui.swap_with_damage"
+
 ///////////////////////////////////////////////////////////////////////////////
 // Runtime configuration properties
 ///////////////////////////////////////////////////////////////////////////////
@@ -288,6 +303,10 @@ public:
     static bool debugLayersUpdates;
     static bool debugOverdraw;
     static bool showDirtyRegions;
+    // TODO: Remove after stabilization period
+    static bool skipEmptyFrames;
+    // TODO: Remove after stabilization period
+    static bool swapBuffersWithDamage;
 
     static DebugLevel debugLevel;
     static OverdrawColorSet overdrawColorSet;
index 3de3086..436946f 100644 (file)
 
 #include "CanvasContext.h"
 
+#include "AnimationContext.h"
+#include "Caches.h"
+#include "DeferredLayerUpdater.h"
 #include "EglManager.h"
+#include "LayerRenderer.h"
+#include "OpenGLRenderer.h"
+#include "Properties.h"
 #include "RenderThread.h"
-#include "../AnimationContext.h"
-#include "../Caches.h"
-#include "../DeferredLayerUpdater.h"
-#include "../renderstate/RenderState.h"
-#include "../renderstate/Stencil.h"
-#include "../LayerRenderer.h"
-#include "../OpenGLRenderer.h"
+#include "renderstate/RenderState.h"
+#include "renderstate/Stencil.h"
 
 #include <algorithm>
+#include <strings.h>
 #include <cutils/properties.h>
 #include <private/hwui/DrawGlInfo.h>
-#include <strings.h>
 
 #define TRIM_MEMORY_COMPLETE 80
 #define TRIM_MEMORY_UI_HIDDEN 20
 
-#define PROPERTY_SKIP_EMPTY_DAMAGE "debug.hwui.skip_empty_damage"
-
-static bool sInitialized = false;
-static bool sSkipEmptyDamage = true;
-
-static void initGlobals() {
-    if (sInitialized) return;
-    sInitialized = true;
-    sSkipEmptyDamage = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE,
-            sSkipEmptyDamage);
-}
-
 namespace android {
 namespace uirenderer {
 namespace renderthread {
@@ -58,9 +47,6 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
         , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
         , mRootRenderNode(rootRenderNode)
         , mJankTracker(thread.timeLord().frameIntervalNanos()) {
-    // Done lazily at first draw instead of at library load to avoid
-    // running pre-zygote fork
-    initGlobals();
     mRenderThread.renderState().registerCanvasContext(this);
     mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
 }
@@ -106,8 +92,8 @@ void CanvasContext::setSurface(ANativeWindow* window) {
     }
 }
 
-void CanvasContext::swapBuffers() {
-    if (CC_UNLIKELY(!mEglManager.swapBuffers(mEglSurface))) {
+void CanvasContext::swapBuffers(const SkRect& dirty, EGLint width, EGLint height) {
+    if (CC_UNLIKELY(!mEglManager.swapBuffers(mEglSurface, dirty, width, height))) {
         setSurface(nullptr);
     }
     mHaveNewSurface = false;
@@ -222,7 +208,7 @@ void CanvasContext::draw() {
     SkRect dirty;
     mDamageAccumulator.finish(&dirty);
 
-    if (dirty.isEmpty() && sSkipEmptyDamage) {
+    if (dirty.isEmpty() && Properties::skipEmptyFrames) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame);
         return;
     }
@@ -267,7 +253,7 @@ void CanvasContext::draw() {
     mCurrentFrameInfo->markSwapBuffers();
 
     if (drew) {
-        swapBuffers();
+        swapBuffers(dirty, width, height);
     } else {
         mEglManager.cancelFrame();
     }
index f5f1f54..8163b0f 100644 (file)
@@ -29,6 +29,7 @@
 #include <cutils/compiler.h>
 #include <EGL/egl.h>
 #include <SkBitmap.h>
+#include <SkRect.h>
 #include <utils/Functor.h>
 #include <utils/Vector.h>
 
@@ -117,7 +118,7 @@ private:
     friend class android::uirenderer::RenderState;
 
     void setSurface(ANativeWindow* window);
-    void swapBuffers();
+    void swapBuffers(const SkRect& dirty, EGLint width, EGLint height);
     void requireSurface();
 
     void requireGlContext();
index 3afca2f..6255f5e 100644 (file)
 
 #include "EglManager.h"
 
-#include "../Caches.h"
-#include "../renderstate/RenderState.h"
+#include "Caches.h"
+#include "Properties.h"
 #include "RenderThread.h"
+#include "renderstate/RenderState.h"
 
 #include <cutils/log.h>
 #include <cutils/properties.h>
@@ -261,7 +262,8 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
     mInFrame = true;
 }
 
-bool EglManager::swapBuffers(EGLSurface surface) {
+bool EglManager::swapBuffers(EGLSurface surface, const SkRect& dirty,
+        EGLint width, EGLint height) {
     mInFrame = false;
 
 #if WAIT_FOR_GPU_COMPLETION
@@ -271,7 +273,37 @@ bool EglManager::swapBuffers(EGLSurface surface) {
     }
 #endif
 
+#ifdef EGL_KHR_swap_buffers_with_damage
+    if (CC_UNLIKELY(Properties::swapBuffersWithDamage)) {
+        SkIRect idirty;
+        dirty.roundOut(&idirty);
+        /*
+         * EGL_KHR_swap_buffers_with_damage spec states:
+         *
+         * The rectangles are specified relative to the bottom-left of the surface
+         * and the x and y components of each rectangle specify the bottom-left
+         * position of that rectangle.
+         *
+         * HWUI does everything with 0,0 being top-left, so need to map
+         * the rect
+         */
+        EGLint y = height - (idirty.y() + idirty.height());
+        // layout: {x, y, width, height}
+        EGLint rects[4] = { idirty.x(), y, idirty.width(), idirty.height() };
+        EGLint numrects = dirty.isEmpty() ? 0 : 1;
+        // TODO: Remove prior to enabling this path by default
+        ALOGD("Swap buffers with damage %d: %d, %d, %d, %d (src="
+                RECT_STRING ")",
+                dirty.isEmpty() ? 0 : 1, rects[0], rects[1], rects[2], rects[3],
+                SK_RECT_ARGS(dirty));
+        eglSwapBuffersWithDamageKHR(mEglDisplay, surface, rects, numrects);
+    } else {
+        eglSwapBuffers(mEglDisplay, surface);
+    }
+#else
     eglSwapBuffers(mEglDisplay, surface);
+#endif
+
     EGLint err = eglGetError();
     if (CC_LIKELY(err == EGL_SUCCESS)) {
         return true;
index b1a18a9..0855516 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <cutils/compiler.h>
 #include <EGL/egl.h>
+#include <SkRect.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/StrongPointer.h>
 
@@ -47,7 +48,7 @@ public:
     // Returns true if the current surface changed, false if it was already current
     bool makeCurrent(EGLSurface surface);
     void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
-    bool swapBuffers(EGLSurface surface);
+    bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height);
     void cancelFrame();
 
     // Returns true iff the surface is now preserving buffers.