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

Commit 61840eb0 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Preliminary Support for region clipping"

parents 82176350 735738c4
Loading
Loading
Loading
Loading
+10 −18
Original line number Diff line number Diff line
@@ -433,20 +433,16 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public boolean clipPath(Path path) {
        // TODO: Implement
        path.computeBounds(mPathBounds, true);
        return nClipRect(mRenderer, mPathBounds.left, mPathBounds.top,
                mPathBounds.right, mPathBounds.bottom, Region.Op.INTERSECT.nativeInt);
        return nClipPath(mRenderer, path.mNativePath, Region.Op.INTERSECT.nativeInt);
    }

    @Override
    public boolean clipPath(Path path, Region.Op op) {
        // TODO: Implement
        path.computeBounds(mPathBounds, true);
        return nClipRect(mRenderer, mPathBounds.left, mPathBounds.top,
                mPathBounds.right, mPathBounds.bottom, op.nativeInt);
        return nClipPath(mRenderer, path.mNativePath, op.nativeInt);
    }

    private static native boolean nClipPath(int renderer, int path, int op);

    @Override
    public boolean clipRect(float left, float top, float right, float bottom) {
        return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
@@ -465,8 +461,8 @@ class GLES20Canvas extends HardwareCanvas {
        return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
    }
    
    private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom,
            int op);
    private static native boolean nClipRect(int renderer, int left, int top,
            int right, int bottom, int op);

    @Override
    public boolean clipRect(Rect rect) {
@@ -492,20 +488,16 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public boolean clipRegion(Region region) {
        // TODO: Implement
        region.getBounds(mClipBounds);
        return nClipRect(mRenderer, mClipBounds.left, mClipBounds.top,
                mClipBounds.right, mClipBounds.bottom, Region.Op.INTERSECT.nativeInt);
        return nClipRegion(mRenderer, region.mNativeRegion, Region.Op.INTERSECT.nativeInt);
    }

    @Override
    public boolean clipRegion(Region region, Region.Op op) {
        // TODO: Implement
        region.getBounds(mClipBounds);
        return nClipRect(mRenderer, mClipBounds.left, mClipBounds.top,
                mClipBounds.right, mClipBounds.bottom, op.nativeInt);
        return nClipRegion(mRenderer, region.mNativeRegion, op.nativeInt);
    }

    private static native boolean nClipRegion(int renderer, int region, int op);

    @Override
    public boolean getClipBounds(Rect bounds) {
        return nGetClipBounds(mRenderer, bounds);
+26 −11
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 * 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.
@@ -14,7 +14,6 @@
 * limitations under the License.
 */


package android.view;

import android.content.ComponentCallbacks2;
@@ -173,6 +172,17 @@ public abstract class HardwareRenderer {
     */
    public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";

    /**
     * Turn on to allow region clipping (see
     * {@link android.graphics.Canvas#clipPath(android.graphics.Path)} and
     * {@link android.graphics.Canvas#clipRegion(android.graphics.Region)}.
     *
     * When this option is turned on a stencil buffer is always required.
     * If this option is off a stencil buffer is only created when the overdraw
     * debugging mode is turned on.
     */
    private static final boolean REGION_CLIPPING_ENABLED = false;

    /**
     * A process can set this flag to false to prevent the use of hardware
     * rendering.
@@ -876,6 +886,7 @@ public abstract class HardwareRenderer {
                changed = true;
                mShowOverdraw = value;

                if (!REGION_CLIPPING_ENABLED) {
                    if (surface != null && isEnabled()) {
                        if (validate()) {
                            sEglConfig = loadEglConfig();
@@ -883,6 +894,7 @@ public abstract class HardwareRenderer {
                        }
                    }
                }
            }

            if (nLoadProperties()) {
                changed = true;
@@ -1752,6 +1764,11 @@ public abstract class HardwareRenderer {

        @Override
        int[] getConfig(boolean dirtyRegions) {
            //noinspection PointlessBooleanExpression
            final int stencilSize = mShowOverdraw || REGION_CLIPPING_ENABLED ?
                    GLES20Canvas.getStencilSize() : 0;
            final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;

            return new int[] {
                    EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
                    EGL_RED_SIZE, 8,
@@ -1760,10 +1777,8 @@ public abstract class HardwareRenderer {
                    EGL_ALPHA_SIZE, 8,
                    EGL_DEPTH_SIZE, 0,
                    EGL_CONFIG_CAVEAT, EGL_NONE,
                    // TODO: Find a better way to choose the stencil size
                    EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0,
                    EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
                            (dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
                    EGL_STENCIL_SIZE, stencilSize,
                    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
                    EGL_NONE
            };
        }
+12 −0
Original line number Diff line number Diff line
@@ -275,6 +275,16 @@ static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
    return renderer->clipRect(float(left), float(top), float(right), float(bottom), op);
}

static bool android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
        OpenGLRenderer* renderer, SkPath* path, SkRegion::Op op) {
    return renderer->clipPath(path, op);
}

static bool android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
        OpenGLRenderer* renderer, SkRegion* region, SkRegion::Op op) {
    return renderer->clipRegion(region, op);
}

static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
        OpenGLRenderer* renderer, jobject rect) {
    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
@@ -961,6 +971,8 @@ static JNINativeMethod gMethods[] = {
    { "nQuickReject",       "(IFFFFI)Z",       (void*) android_view_GLES20Canvas_quickReject },
    { "nClipRect",          "(IFFFFI)Z",       (void*) android_view_GLES20Canvas_clipRectF },
    { "nClipRect",          "(IIIIII)Z",       (void*) android_view_GLES20Canvas_clipRect },
    { "nClipPath",          "(III)Z",          (void*) android_view_GLES20Canvas_clipPath },
    { "nClipRegion",        "(III)Z",          (void*) android_view_GLES20Canvas_clipRegion },

    { "nTranslate",         "(IFF)V",          (void*) android_view_GLES20Canvas_translate },
    { "nRotate",            "(IF)V",           (void*) android_view_GLES20Canvas_rotate },
+3 −0
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@
// Turn on to enable layers debugging when rendered as regions
#define DEBUG_LAYERS_AS_REGIONS 0

// Turn on to enable debugging when the clip is not a rect
#define DEBUG_CLIP_REGIONS 0

// Turn on to display debug info about vertex/fragment shaders
#define DEBUG_PROGRAMS 0

+54 −14
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ const char* DisplayList::OP_NAMES[] = {
    "SetMatrix",
    "ConcatMatrix",
    "ClipRect",
    "ClipPath",
    "ClipRegion",
    "DrawDisplayList",
    "DrawLayer",
    "DrawBitmap",
@@ -166,6 +168,10 @@ void DisplayList::clearResources() {
        delete mPaints.itemAt(i);
    }

    for (size_t i = 0; i < mRegions.size(); i++) {
        delete mRegions.itemAt(i);
    }

    for (size_t i = 0; i < mPaths.size(); i++) {
        SkPath* path = mPaths.itemAt(i);
        caches.pathCache.remove(path);
@@ -182,6 +188,7 @@ void DisplayList::clearResources() {
    mShaders.clear();
    mSourcePaths.clear();
    mPaints.clear();
    mRegions.clear();
    mPaths.clear();
    mMatrices.clear();
    mLayers.clear();
@@ -259,20 +266,10 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde

    caches.resourceCache.unlock();

    const Vector<SkPaint*>& paints = recorder.getPaints();
    for (size_t i = 0; i < paints.size(); i++) {
        mPaints.add(paints.itemAt(i));
    }

    const Vector<SkPath*>& paths = recorder.getPaths();
    for (size_t i = 0; i < paths.size(); i++) {
        mPaths.add(paths.itemAt(i));
    }

    const Vector<SkMatrix*>& matrices = recorder.getMatrices();
    for (size_t i = 0; i < matrices.size(); i++) {
        mMatrices.add(matrices.itemAt(i));
    }
    mPaints.appendVector(recorder.getPaints());
    mRegions.appendVector(recorder.getRegions());
    mPaths.appendVector(recorder.getPaths());
    mMatrices.appendVector(recorder.getMatrices());
}

void DisplayList::init() {
@@ -429,6 +426,18 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
                        f1, f2, f3, f4, regionOp);
            }
            break;
            case ClipPath: {
                SkPath* path = getPath();
                int regionOp = getInt();
                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
            }
            break;
            case ClipRegion: {
                SkRegion* region = getRegion();
                int regionOp = getInt();
                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
            }
            break;
            case DrawDisplayList: {
                DisplayList* displayList = getDisplayList();
                int32_t flags = getInt();
@@ -1031,6 +1040,20 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag
                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
            }
            break;
            case ClipPath: {
                SkPath* path = getPath();
                int32_t regionOp = getInt();
                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
                renderer.clipPath(path, (SkRegion::Op) regionOp);
            }
            break;
            case ClipRegion: {
                SkRegion* region = getRegion();
                int32_t regionOp = getInt();
                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
                renderer.clipRegion(region, (SkRegion::Op) regionOp);
            }
            break;
            case DrawDisplayList: {
                DisplayList* displayList = getDisplayList();
                int32_t flags = getInt();
@@ -1415,6 +1438,9 @@ void DisplayListRenderer::reset() {
    mPaints.clear();
    mPaintMap.clear();

    mRegions.clear();
    mRegionMap.clear();

    mPaths.clear();
    mPathMap.clear();

@@ -1571,6 +1597,20 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}

bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
    addOp(DisplayList::ClipPath);
    addPath(path);
    addInt(op);
    return OpenGLRenderer::clipPath(path, op);
}

bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
    addOp(DisplayList::ClipRegion);
    addRegion(region);
    addInt(op);
    return OpenGLRenderer::clipRegion(region, op);
}

status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
        Rect& dirty, int32_t flags, uint32_t level) {
    // dirty is an out parameter and should not be recorded,
Loading