Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 448eaa5d authored by John Reck's avatar John Reck Committed by Android Git Automerger
Browse files

am a8dca228: Merge "Add eglSwapBuffersWithDamageKHR support" into mnc-dev

* commit 'a8dca228':
  Add eglSwapBuffersWithDamageKHR support
parents 5bb14329 a8dca228
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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);
+19 −0
Original line number Diff line number Diff line
@@ -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;
+13 −27
Original line number Diff line number Diff line
@@ -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();
    }
+2 −1
Original line number Diff line number Diff line
@@ -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();
+35 −3
Original line number Diff line number Diff line
@@ -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;
Loading