Merge "Refactor HWUI to better handle Canvas DrawFilters."
This commit is contained in:
committed by
Android (Google) Code Review
commit
425cc668a9
@@ -517,16 +517,10 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
@Override
|
||||
public void setDrawFilter(DrawFilter filter) {
|
||||
mFilter = filter;
|
||||
if (filter == null) {
|
||||
nResetPaintFilter(mRenderer);
|
||||
} else if (filter instanceof PaintFlagsDrawFilter) {
|
||||
PaintFlagsDrawFilter flagsFilter = (PaintFlagsDrawFilter) filter;
|
||||
nSetupPaintFilter(mRenderer, flagsFilter.clearBits, flagsFilter.setBits);
|
||||
}
|
||||
nSetDrawFilter(mRenderer, (filter != null) ? filter.mNativeInt : 0);
|
||||
}
|
||||
|
||||
private static native void nResetPaintFilter(long renderer);
|
||||
private static native void nSetupPaintFilter(long renderer, int clearBits, int setBits);
|
||||
private static native void nSetDrawFilter(long renderer, long nativeFilter);
|
||||
|
||||
@Override
|
||||
public DrawFilter getDrawFilter() {
|
||||
|
||||
@@ -587,16 +587,11 @@ static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
|
||||
// Draw filters
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jint clearBits, jint setBits) {
|
||||
static void android_view_GLES20Canvas_setDrawFilter(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jlong filterPtr) {
|
||||
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
|
||||
renderer->setupPaintFilter(clearBits, setBits);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr) {
|
||||
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
|
||||
renderer->resetPaintFilter();
|
||||
SkDrawFilter* filter = reinterpret_cast<SkDrawFilter*>(filterPtr);
|
||||
renderer->setDrawFilter(filter);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -936,8 +931,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath },
|
||||
{ "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines },
|
||||
|
||||
{ "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter },
|
||||
{ "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter },
|
||||
{ "nSetDrawFilter", "(JJ)V", (void*) android_view_GLES20Canvas_setDrawFilter },
|
||||
|
||||
{ "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
|
||||
{ "nDrawText", "(JLjava/lang/String;IIFFIJJ)V",
|
||||
|
||||
@@ -24,8 +24,11 @@ package android.graphics;
|
||||
*/
|
||||
public class DrawFilter {
|
||||
|
||||
// this is set by subclasses, but don't make it public
|
||||
/* package */ long mNativeInt; // pointer to native object
|
||||
/**
|
||||
* this is set by subclasses
|
||||
* @hide
|
||||
*/
|
||||
public long mNativeInt;
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
package android.graphics;
|
||||
|
||||
public class PaintFlagsDrawFilter extends DrawFilter {
|
||||
/** @hide **/
|
||||
public final int clearBits;
|
||||
/** @hide **/
|
||||
public final int setBits;
|
||||
|
||||
/**
|
||||
* Subclass of DrawFilter that affects every paint by first clearing
|
||||
* the specified clearBits in the paint's flags, and then setting the
|
||||
@@ -31,8 +26,6 @@ public class PaintFlagsDrawFilter extends DrawFilter {
|
||||
* @param setBits These bits will be set in the paint's flags
|
||||
*/
|
||||
public PaintFlagsDrawFilter(int clearBits, int setBits) {
|
||||
this.clearBits = clearBits;
|
||||
this.setBits = setBits;
|
||||
// our native constructor can return 0, if the specified bits
|
||||
// are effectively a no-op
|
||||
mNativeInt = nativeConstructor(clearBits, setBits);
|
||||
|
||||
@@ -235,26 +235,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Draw Modifiers compatibility check
|
||||
*
|
||||
* Shadows are ignored, as only text uses them, and in that case they are drawn
|
||||
* per-DrawTextOp, before the unified text draw. Because of this, it's always safe to merge
|
||||
* text UNLESS a later draw's shadow should overlays a previous draw's text. This is covered
|
||||
* above with the intersection check.
|
||||
*
|
||||
* OverrideLayerAlpha is also ignored, as it's only used for drawing layers, which are never
|
||||
* merged.
|
||||
*
|
||||
* These ignore cases prevent us from simply memcmp'ing the drawModifiers
|
||||
*/
|
||||
const DrawModifiers& lhsMod = lhs->mDrawModifiers;
|
||||
const DrawModifiers& rhsMod = rhs->mDrawModifiers;
|
||||
|
||||
// Draw filter testing expects bit fields to be clear if filter not set.
|
||||
if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false;
|
||||
if (lhsMod.mPaintFilterClearBits != rhsMod.mPaintFilterClearBits) return false;
|
||||
if (lhsMod.mPaintFilterSetBits != rhsMod.mPaintFilterSetBits) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,10 +201,6 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
const SkPaint* getPaint(OpenGLRenderer& renderer) {
|
||||
return renderer.filterPaint(mPaint);
|
||||
}
|
||||
|
||||
// Helper method for determining op opaqueness. Assumes op fills its bounds in local
|
||||
// coordinates, and that paint's alpha is used
|
||||
inline bool isOpaqueOverBounds(const DeferredDisplayState& state) {
|
||||
@@ -234,7 +230,7 @@ protected:
|
||||
|
||||
}
|
||||
|
||||
const SkPaint* mPaint; // should be accessed via getPaint() when applying
|
||||
const SkPaint* mPaint;
|
||||
bool mQuickRejected;
|
||||
};
|
||||
|
||||
@@ -608,39 +604,6 @@ private:
|
||||
const SkRegion* mRegion;
|
||||
};
|
||||
|
||||
class ResetPaintFilterOp : public StateOp {
|
||||
public:
|
||||
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
|
||||
renderer.resetPaintFilter();
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
OP_LOGS("ResetPaintFilter");
|
||||
}
|
||||
|
||||
virtual const char* name() { return "ResetPaintFilter"; }
|
||||
};
|
||||
|
||||
class SetupPaintFilterOp : public StateOp {
|
||||
public:
|
||||
SetupPaintFilterOp(int clearBits, int setBits)
|
||||
: mClearBits(clearBits), mSetBits(setBits) {}
|
||||
|
||||
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
|
||||
renderer.setupPaintFilter(mClearBits, mSetBits);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
|
||||
}
|
||||
|
||||
virtual const char* name() { return "SetupPaintFilter"; }
|
||||
|
||||
private:
|
||||
int mClearBits;
|
||||
int mSetBits;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DRAW OPERATIONS - these are operations that can draw to the canvas's device
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -659,7 +622,7 @@ public:
|
||||
}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawBitmap(mBitmap, getPaint(renderer));
|
||||
return renderer.drawBitmap(mBitmap, mPaint);
|
||||
}
|
||||
|
||||
AssetAtlas::Entry* getAtlasEntry() {
|
||||
@@ -764,7 +727,7 @@ public:
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
|
||||
mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
|
||||
getPaint(renderer));
|
||||
mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -790,7 +753,7 @@ public:
|
||||
: DrawBitmapOp(bitmap, paint) {}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawBitmapData(mBitmap, getPaint(renderer));
|
||||
return renderer.drawBitmapData(mBitmap, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -815,7 +778,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
|
||||
mVertices, mColors, getPaint(renderer));
|
||||
mVertices, mColors, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -945,7 +908,7 @@ public:
|
||||
}
|
||||
|
||||
return renderer.drawPatches(mBitmap, getAtlasEntry(),
|
||||
&vertices[0], indexCount, getPaint(renderer));
|
||||
&vertices[0], indexCount, mPaint);
|
||||
}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
@@ -953,7 +916,7 @@ public:
|
||||
// This method won't perform the quickReject() since we've already done it at this point
|
||||
return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
|
||||
mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
|
||||
getPaint(renderer));
|
||||
mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1037,7 +1000,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
|
||||
mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
|
||||
mLocalBounds.right, mLocalBounds.bottom, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1061,7 +1024,7 @@ public:
|
||||
mRects(rects), mCount(count) {}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawRects(mRects, mCount, getPaint(renderer));
|
||||
return renderer.drawRects(mRects, mCount, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1088,7 +1051,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
|
||||
mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
|
||||
mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1120,7 +1083,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
|
||||
*mRx, *mRy, getPaint(renderer));
|
||||
*mRx, *mRy, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1146,7 +1109,7 @@ public:
|
||||
mX(x), mY(y), mRadius(radius) {}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
|
||||
return renderer.drawCircle(mX, mY, mRadius, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1167,7 +1130,7 @@ public:
|
||||
: DrawOp(paint), mX(x), mY(y), mRadius(radius) {}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawCircle(*mX, *mY, *mRadius, getPaint(renderer));
|
||||
return renderer.drawCircle(*mX, *mY, *mRadius, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1189,7 +1152,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
|
||||
mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
|
||||
mLocalBounds.right, mLocalBounds.bottom, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1209,7 +1172,7 @@ public:
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
|
||||
mLocalBounds.right, mLocalBounds.bottom,
|
||||
mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
|
||||
mStartAngle, mSweepAngle, mUseCenter, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1238,13 +1201,12 @@ public:
|
||||
}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawPath(mPath, getPaint(renderer));
|
||||
return renderer.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
|
||||
const DeferredDisplayState& state) {
|
||||
const SkPaint* paint = getPaint(renderer);
|
||||
renderer.getCaches().pathCache.precache(mPath, paint);
|
||||
renderer.getCaches().pathCache.precache(mPath, mPaint);
|
||||
|
||||
deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
|
||||
}
|
||||
@@ -1268,7 +1230,7 @@ public:
|
||||
}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawLines(mPoints, mCount, getPaint(renderer));
|
||||
return renderer.drawLines(mPoints, mCount, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1295,7 +1257,7 @@ public:
|
||||
: DrawLinesOp(points, count, paint) {}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
|
||||
return renderer.drawPoints(mPoints, mCount, mPaint);
|
||||
}
|
||||
|
||||
virtual void output(int level, uint32_t logFlags) const {
|
||||
@@ -1320,9 +1282,8 @@ public:
|
||||
|
||||
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
|
||||
const DeferredDisplayState& state) {
|
||||
const SkPaint* paint = getPaint(renderer);
|
||||
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
|
||||
fontRenderer.precache(paint, mText, mCount, SkMatrix::I());
|
||||
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint);
|
||||
fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I());
|
||||
|
||||
deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
|
||||
DeferredDisplayList::kOpBatch_Text :
|
||||
@@ -1346,7 +1307,7 @@ public:
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
|
||||
mHOffset, mVOffset, getPaint(renderer));
|
||||
mHOffset, mVOffset, mPaint);
|
||||
}
|
||||
|
||||
virtual const char* name() { return "DrawTextOnPath"; }
|
||||
@@ -1366,7 +1327,7 @@ public:
|
||||
}
|
||||
|
||||
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
|
||||
return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
|
||||
return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint);
|
||||
}
|
||||
|
||||
virtual const char* name() { return "DrawPosText"; }
|
||||
@@ -1386,12 +1347,11 @@ public:
|
||||
|
||||
virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
|
||||
const DeferredDisplayState& state) {
|
||||
const SkPaint* paint = getPaint(renderer);
|
||||
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
|
||||
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(mPaint);
|
||||
SkMatrix transform;
|
||||
renderer.findBestFontTransform(state.mMatrix, &transform);
|
||||
if (mPrecacheTransform != transform) {
|
||||
fontRenderer.precache(paint, mText, mCount, transform);
|
||||
fontRenderer.precache(mPaint, mText, mCount, transform);
|
||||
mPrecacheTransform = transform;
|
||||
}
|
||||
deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
|
||||
@@ -1413,7 +1373,7 @@ public:
|
||||
Rect bounds;
|
||||
getLocalBounds(bounds);
|
||||
return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
|
||||
mPositions, getPaint(renderer), mTotalAdvance, bounds);
|
||||
mPositions, mPaint, mTotalAdvance, bounds);
|
||||
}
|
||||
|
||||
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
|
||||
@@ -1428,7 +1388,7 @@ public:
|
||||
// quickReject() will not occure in drawText() so we can use mLocalBounds
|
||||
// directly, we do not need to account for shadow by calling getLocalBounds()
|
||||
status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
|
||||
op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds,
|
||||
op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds,
|
||||
drawOpMode);
|
||||
}
|
||||
return status;
|
||||
|
||||
@@ -437,12 +437,8 @@ status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkP
|
||||
return DrawGlInfo::kStatusDone;
|
||||
}
|
||||
|
||||
void DisplayListRenderer::resetPaintFilter() {
|
||||
addStateOp(new (alloc()) ResetPaintFilterOp());
|
||||
}
|
||||
|
||||
void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
|
||||
addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
|
||||
void DisplayListRenderer::setDrawFilter(SkDrawFilter* filter) {
|
||||
mDrawFilter.reset(filter);
|
||||
}
|
||||
|
||||
void DisplayListRenderer::insertReorderBarrier(bool enableReorder) {
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
||||
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
||||
|
||||
#include <SkDrawFilter.h>
|
||||
#include <SkMatrix.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkPath.h>
|
||||
#include <SkRegion.h>
|
||||
#include <SkTLazy.h>
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
#include "DisplayList.h"
|
||||
@@ -96,9 +98,8 @@ public:
|
||||
virtual bool clipPath(const SkPath* path, SkRegion::Op op);
|
||||
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
|
||||
|
||||
// Misc - should be implemented with SkPaint inspection
|
||||
virtual void resetPaintFilter();
|
||||
virtual void setupPaintFilter(int clearBits, int setBits);
|
||||
// Misc
|
||||
virtual void setDrawFilter(SkDrawFilter* filter);
|
||||
|
||||
bool isCurrentTransformSimple() {
|
||||
return currentTransform()->isSimple();
|
||||
@@ -221,15 +222,27 @@ private:
|
||||
inline const SkPaint* refPaint(const SkPaint* paint) {
|
||||
if (!paint) return NULL;
|
||||
|
||||
const SkPaint* paintCopy = mPaintMap.valueFor(paint);
|
||||
if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
|
||||
paintCopy = new SkPaint(*paint);
|
||||
// replaceValueFor() performs an add if the entry doesn't exist
|
||||
mPaintMap.replaceValueFor(paint, paintCopy);
|
||||
mDisplayListData->paints.add(paintCopy);
|
||||
// If there is a draw filter apply it here and store the modified paint
|
||||
// so that we don't need to modify the paint every time we access it.
|
||||
SkTLazy<SkPaint> filteredPaint;
|
||||
if (mDrawFilter.get()) {
|
||||
paint = filteredPaint.init();
|
||||
mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
|
||||
}
|
||||
|
||||
return paintCopy;
|
||||
// compute the hash key for the paint and check the cache.
|
||||
const uint32_t key = paint->getHash();
|
||||
const SkPaint* cachedPaint = mPaintMap.valueFor(key);
|
||||
// In the unlikely event that 2 unique paints have the same hash we do a
|
||||
// object equality check to ensure we don't erroneously dedup them.
|
||||
if (cachedPaint == NULL || *cachedPaint != *paint) {
|
||||
cachedPaint = new SkPaint(*paint);
|
||||
// replaceValueFor() performs an add if the entry doesn't exist
|
||||
mPaintMap.replaceValueFor(key, cachedPaint);
|
||||
mDisplayListData->paints.add(cachedPaint);
|
||||
}
|
||||
|
||||
return cachedPaint;
|
||||
}
|
||||
|
||||
inline SkPaint* copyPaint(const SkPaint* paint) {
|
||||
@@ -285,7 +298,7 @@ private:
|
||||
return patch;
|
||||
}
|
||||
|
||||
DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
|
||||
DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
|
||||
DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
|
||||
DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
|
||||
|
||||
@@ -300,6 +313,8 @@ private:
|
||||
|
||||
int mRestoreSaveCount;
|
||||
|
||||
SkAutoTUnref<SkDrawFilter> mDrawFilter;
|
||||
|
||||
friend class RenderNode;
|
||||
|
||||
}; // class DisplayListRenderer
|
||||
|
||||
@@ -3057,47 +3057,10 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Draw filters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void OpenGLRenderer::resetPaintFilter() {
|
||||
// when clearing the PaintFilter, the masks should also be cleared for simple DrawModifier
|
||||
// comparison, see MergingDrawBatch::canMergeWith
|
||||
mDrawModifiers.mHasDrawFilter = false;
|
||||
mDrawModifiers.mPaintFilterClearBits = 0;
|
||||
mDrawModifiers.mPaintFilterSetBits = 0;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) {
|
||||
// TODO: don't bother with boolean, it's redundant with clear/set bits
|
||||
mDrawModifiers.mHasDrawFilter = true;
|
||||
mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags;
|
||||
mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
|
||||
}
|
||||
|
||||
const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
|
||||
// TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp
|
||||
// to avoid clobbering 0x02 paint flag
|
||||
|
||||
// Equivalent to the Java Paint's FILTER_BITMAP_FLAG.
|
||||
static const uint32_t sFilterBitmapFlag = 0x02;
|
||||
|
||||
if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
|
||||
return paint;
|
||||
}
|
||||
|
||||
const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits;
|
||||
const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits;
|
||||
|
||||
const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits;
|
||||
mFilteredPaint = *paint;
|
||||
mFilteredPaint.setFlags(flags);
|
||||
|
||||
// check if paint filter trying to override bitmap filter
|
||||
if ((clearBits | setBits) & sFilterBitmapFlag) {
|
||||
mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag
|
||||
? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
|
||||
}
|
||||
|
||||
return &mFilteredPaint;
|
||||
void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) {
|
||||
// We should never get here since we apply the draw filter when stashing
|
||||
// the paints in the DisplayList.
|
||||
LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -70,11 +70,6 @@ struct DrawModifiers {
|
||||
}
|
||||
|
||||
float mOverrideLayerAlpha;
|
||||
|
||||
// Draw filters
|
||||
bool mHasDrawFilter;
|
||||
int mPaintFilterClearBits;
|
||||
int mPaintFilterSetBits;
|
||||
};
|
||||
|
||||
enum StateDeferFlags {
|
||||
@@ -205,14 +200,11 @@ public:
|
||||
status_t drawShadow(float casterAlpha,
|
||||
const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer);
|
||||
|
||||
virtual void resetPaintFilter();
|
||||
virtual void setupPaintFilter(int clearBits, int setBits);
|
||||
virtual void setDrawFilter(SkDrawFilter* filter);
|
||||
|
||||
// If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer)
|
||||
void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; }
|
||||
|
||||
const SkPaint* filterPaint(const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Store the current display state (most importantly, the current clip and transform), and
|
||||
* additionally map the state's bounds from local to window coordinates.
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#include <SkColorFilter.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkRegion.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include "AssetAtlas.h"
|
||||
|
||||
class SkDrawFilter;
|
||||
|
||||
namespace android {
|
||||
|
||||
class Functor;
|
||||
@@ -173,9 +174,8 @@ public:
|
||||
virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
|
||||
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
|
||||
|
||||
// Misc - should be implemented with SkPaint inspection
|
||||
virtual void resetPaintFilter() = 0;
|
||||
virtual void setupPaintFilter(int clearBits, int setBits) = 0;
|
||||
// Misc
|
||||
virtual void setDrawFilter(SkDrawFilter* filter) = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Canvas draw operations
|
||||
|
||||
Reference in New Issue
Block a user