am 61840eb0: Merge "Preliminary Support for region clipping"
* commit '61840eb03882e1a964ae971725bd21229c3db42c': Preliminary Support for region clipping
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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,10 +886,12 @@ public abstract class HardwareRenderer {
|
||||
changed = true;
|
||||
mShowOverdraw = value;
|
||||
|
||||
if (surface != null && isEnabled()) {
|
||||
if (validate()) {
|
||||
sEglConfig = loadEglConfig();
|
||||
invalidate(surface);
|
||||
if (!REGION_CLIPPING_ENABLED) {
|
||||
if (surface != null && isEnabled()) {
|
||||
if (validate()) {
|
||||
sEglConfig = loadEglConfig();
|
||||
invalidate(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,14 +1777,12 @@ 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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
void initCaches() {
|
||||
GLES20Canvas.initCaches();
|
||||
|
||||
@@ -274,6 +274,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());
|
||||
@@ -960,6 +970,8 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nQuickReject", "(IFFFF)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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -86,6 +86,8 @@ public:
|
||||
SetMatrix,
|
||||
ConcatMatrix,
|
||||
ClipRect,
|
||||
ClipPath,
|
||||
ClipRegion,
|
||||
// Drawing operations
|
||||
DrawDisplayList,
|
||||
DrawLayer,
|
||||
@@ -458,6 +460,10 @@ private:
|
||||
return (SkPath*) getInt();
|
||||
}
|
||||
|
||||
SkRegion* getRegion() {
|
||||
return (SkRegion*) getInt();
|
||||
}
|
||||
|
||||
SkPaint* getPaint(OpenGLRenderer& renderer) {
|
||||
return renderer.filterPaint((SkPaint*) getInt());
|
||||
}
|
||||
@@ -497,6 +503,7 @@ private:
|
||||
Vector<SkPaint*> mPaints;
|
||||
Vector<SkPath*> mPaths;
|
||||
SortedVector<SkPath*> mSourcePaths;
|
||||
Vector<SkRegion*> mRegions;
|
||||
Vector<SkMatrix*> mMatrices;
|
||||
Vector<SkiaShader*> mShaders;
|
||||
Vector<Layer*> mLayers;
|
||||
@@ -578,6 +585,8 @@ public:
|
||||
virtual void concatMatrix(SkMatrix* matrix);
|
||||
|
||||
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
virtual bool clipPath(SkPath* path, SkRegion::Op op);
|
||||
virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
|
||||
|
||||
virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
|
||||
uint32_t level = 0);
|
||||
@@ -658,6 +667,10 @@ public:
|
||||
return mSourcePaths;
|
||||
}
|
||||
|
||||
const Vector<SkRegion*>& getRegions() const {
|
||||
return mRegions;
|
||||
}
|
||||
|
||||
const Vector<Layer*>& getLayers() const {
|
||||
return mLayers;
|
||||
}
|
||||
@@ -803,6 +816,26 @@ private:
|
||||
return paintCopy;
|
||||
}
|
||||
|
||||
inline SkRegion* addRegion(SkRegion* region) {
|
||||
if (!region) {
|
||||
addInt((int) NULL);
|
||||
return region;
|
||||
}
|
||||
|
||||
SkRegion* regionCopy = mRegionMap.valueFor(region);
|
||||
// TODO: Add generation ID to SkRegion
|
||||
if (regionCopy == NULL) {
|
||||
regionCopy = new SkRegion(*region);
|
||||
// replaceValueFor() performs an add if the entry doesn't exist
|
||||
mRegionMap.replaceValueFor(region, regionCopy);
|
||||
mRegions.add(regionCopy);
|
||||
}
|
||||
|
||||
addInt((int) regionCopy);
|
||||
|
||||
return regionCopy;
|
||||
}
|
||||
|
||||
inline void addDisplayList(DisplayList* displayList) {
|
||||
// TODO: To be safe, the display list should be ref-counted in the
|
||||
// resources cache, but we rely on the caller (UI toolkit) to
|
||||
@@ -877,6 +910,9 @@ private:
|
||||
|
||||
SortedVector<SkPath*> mSourcePaths;
|
||||
|
||||
Vector<SkRegion*> mRegions;
|
||||
DefaultKeyedVector<SkRegion*, SkRegion*> mRegionMap;
|
||||
|
||||
Vector<SkiaShader*> mShaders;
|
||||
DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
|
||||
|
||||
|
||||
@@ -1288,10 +1288,38 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom,
|
||||
bool clipped = mSnapshot->clip(left, top, right, bottom, op);
|
||||
if (clipped) {
|
||||
dirtyClip();
|
||||
#if DEBUG_CLIP_REGIONS
|
||||
if (!isDeferred() && mSnapshot->clipRegion && !mSnapshot->clipRegion->isRect()) {
|
||||
int count = 0;
|
||||
Vector<float> rects;
|
||||
SkRegion::Iterator it(*mSnapshot->clipRegion);
|
||||
while (!it.done()) {
|
||||
const SkIRect& r = it.rect();
|
||||
rects.push(r.fLeft);
|
||||
rects.push(r.fTop);
|
||||
rects.push(r.fRight);
|
||||
rects.push(r.fBottom);
|
||||
count++;
|
||||
it.next();
|
||||
}
|
||||
|
||||
drawColorRects(rects.array(), count, 0x7f00ff00, SkXfermode::kSrcOver_Mode, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return !mSnapshot->clipRect->isEmpty();
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
|
||||
const SkRect& bounds = path->getBounds();
|
||||
return clipRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, op);
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
|
||||
const SkIRect& bounds = region->getBounds();
|
||||
return clipRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, op);
|
||||
}
|
||||
|
||||
Rect* OpenGLRenderer::getClipRect() {
|
||||
return mSnapshot->clipRect;
|
||||
}
|
||||
@@ -3046,6 +3074,19 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint
|
||||
return DrawGlInfo::kStatusDone;
|
||||
}
|
||||
|
||||
int color = paint->getColor();
|
||||
// If a shader is set, preserve only the alpha
|
||||
if (mShader) {
|
||||
color |= 0x00ffffff;
|
||||
}
|
||||
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
|
||||
|
||||
return drawColorRects(rects, count, color, mode);
|
||||
}
|
||||
|
||||
status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color,
|
||||
SkXfermode::Mode mode, bool ignoreTransform) {
|
||||
|
||||
float left = FLT_MAX;
|
||||
float top = FLT_MAX;
|
||||
float right = FLT_MIN;
|
||||
@@ -3081,13 +3122,6 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint
|
||||
|
||||
if (count == 0) return DrawGlInfo::kStatusDone;
|
||||
|
||||
int color = paint->getColor();
|
||||
// If a shader is set, preserve only the alpha
|
||||
if (mShader) {
|
||||
color |= 0x00ffffff;
|
||||
}
|
||||
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
|
||||
|
||||
setupDraw();
|
||||
setupDrawNoTexture();
|
||||
setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
|
||||
@@ -3096,7 +3130,7 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint
|
||||
setupDrawBlending(mode);
|
||||
setupDrawProgram();
|
||||
setupDrawDirtyRegionsDisabled();
|
||||
setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, ignoreTransform, true);
|
||||
setupDrawColorUniforms();
|
||||
setupDrawShaderUniforms();
|
||||
setupDrawColorFilterUniforms();
|
||||
|
||||
@@ -164,6 +164,8 @@ public:
|
||||
ANDROID_API bool quickReject(float left, float top, float right, float bottom);
|
||||
bool quickRejectNoScissor(float left, float top, float right, float bottom);
|
||||
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
virtual bool clipPath(SkPath* path, SkRegion::Op op);
|
||||
virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
|
||||
virtual Rect* getClipRect();
|
||||
|
||||
virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
|
||||
@@ -498,7 +500,8 @@ private:
|
||||
|
||||
/**
|
||||
* Draws a colored rectangle with the specified color. The specified coordinates
|
||||
* are transformed by the current snapshot's transform matrix.
|
||||
* are transformed by the current snapshot's transform matrix unless specified
|
||||
* otherwise.
|
||||
*
|
||||
* @param left The left coordinate of the rectangle
|
||||
* @param top The top coordinate of the rectangle
|
||||
@@ -511,6 +514,20 @@ private:
|
||||
void drawColorRect(float left, float top, float right, float bottom,
|
||||
int color, SkXfermode::Mode mode, bool ignoreTransform = false);
|
||||
|
||||
/**
|
||||
* Draws a series of colored rectangles with the specified color. The specified
|
||||
* coordinates are transformed by the current snapshot's transform matrix unless
|
||||
* specified otherwise.
|
||||
*
|
||||
* @param rects A list of rectangles, 4 floats (left, top, right, bottom)
|
||||
* per rectangle
|
||||
* @param color The rectangles' ARGB color, defined as a packed 32 bits word
|
||||
* @param mode The Skia xfermode to use
|
||||
* @param ignoreTransform True if the current transform should be ignored
|
||||
*/
|
||||
status_t drawColorRects(const float* rects, int count, int color,
|
||||
SkXfermode::Mode mode, bool ignoreTransform = false);
|
||||
|
||||
/**
|
||||
* Draws the shape represented by the specified path texture.
|
||||
* This method invokes drawPathTexture() but takes into account
|
||||
|
||||
@@ -130,6 +130,7 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
|
||||
switch (op) {
|
||||
case SkRegion::kIntersect_Op: {
|
||||
if (CC_UNLIKELY(clipRegion)) {
|
||||
ensureClipRegion();
|
||||
clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op);
|
||||
} else {
|
||||
clipped = clipRect->intersect(r);
|
||||
@@ -142,6 +143,7 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
|
||||
}
|
||||
case SkRegion::kUnion_Op: {
|
||||
if (CC_UNLIKELY(clipRegion)) {
|
||||
ensureClipRegion();
|
||||
clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op);
|
||||
} else {
|
||||
clipped = clipRect->unionWith(r);
|
||||
|
||||
@@ -18,13 +18,7 @@ package com.android.test.hwui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Region;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
@@ -50,8 +44,10 @@ public class ClipRegionActivity extends Activity {
|
||||
canvas.save();
|
||||
canvas.clipRect(100.0f, 100.0f, getWidth() - 100.0f, getHeight() - 100.0f,
|
||||
Region.Op.DIFFERENCE);
|
||||
canvas.drawARGB(255, 255, 0, 0);
|
||||
canvas.drawARGB(128, 255, 0, 0);
|
||||
canvas.restore();
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user