Add eglSwapBuffersWithDamageKHR support
BUG: 20761426 Disabled temporarily Change-Id: I0b6b6f0eebab886145e13fa35aefe76826965cf5
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user