summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2015-05-08 10:04:36 -0700
committerJohn Reck <jreck@google.com>2015-05-08 10:48:57 -0700
commitd04794a9a3f9edc8b7ca336175d66eb81a8f55fa (patch)
treeb1fb28d9c72377bc981e5242ad58210cf2bd33bf
parenta0698b617f1efc71d5301f98aead822e266ec5d6 (diff)
downloadframeworks_base-d04794a9a3f9edc8b7ca336175d66eb81a8f55fa.zip
frameworks_base-d04794a9a3f9edc8b7ca336175d66eb81a8f55fa.tar.gz
frameworks_base-d04794a9a3f9edc8b7ca336175d66eb81a8f55fa.tar.bz2
Add eglSwapBuffersWithDamageKHR support
BUG: 20761426 Disabled temporarily Change-Id: I0b6b6f0eebab886145e13fa35aefe76826965cf5
-rw-r--r--libs/hwui/Properties.cpp5
-rw-r--r--libs/hwui/Properties.h19
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp40
-rw-r--r--libs/hwui/renderthread/CanvasContext.h3
-rw-r--r--libs/hwui/renderthread/EglManager.cpp38
-rw-r--r--libs/hwui/renderthread/EglManager.h3
6 files changed, 76 insertions, 32 deletions
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index fd32b6f..723a177 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -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);
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 46fa940..cb5560f 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -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;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 3de3086..436946f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -16,36 +16,25 @@
#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();
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index f5f1f54..8163b0f 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -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();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 3afca2f..6255f5e 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -16,9 +16,10 @@
#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;
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index b1a18a9..0855516 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -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.