From 24c00216687ac87fe531dc4d4168ac0c0ca04ea6 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 14 Jan 2011 15:31:00 -0800 Subject: Copy shaders when recording them in display lists. Change-Id: I3f22dd35f1e31c9e5102955d76548098b7b0cd8d --- libs/hwui/DisplayListRenderer.cpp | 22 ++++++--------- libs/hwui/DisplayListRenderer.h | 33 ++++++++++++++++------- libs/hwui/SkiaShader.cpp | 56 +++++++++++++++++++++++++++++++++++++++ libs/hwui/SkiaShader.h | 34 ++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 24 deletions(-) (limited to 'libs') diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 75b1671..747543f 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -128,10 +128,10 @@ DisplayList::~DisplayList() { } mBitmapResources.clear(); - for (size_t i = 0; i < mShaderResources.size(); i++) { - caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i)); + for (size_t i = 0; i < mShaders.size(); i++) { + delete mShaders.itemAt(i); } - mShaderResources.clear(); + mShaders.clear(); for (size_t i = 0; i < mPaints.size(); i++) { delete mPaints.itemAt(i); @@ -179,11 +179,9 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde caches.resourceCache.incrementRefcount(resource); } - const Vector &shaderResources = recorder.getShaderResources(); - for (size_t i = 0; i < shaderResources.size(); i++) { - SkiaShader* resource = shaderResources.itemAt(i); - mShaderResources.add(resource); - caches.resourceCache.incrementRefcount(resource); + const Vector &shaders = recorder.getShaders(); + for (size_t i = 0; i < shaders.size(); i++) { + mShaders.add(shaders.itemAt(i)); } const Vector &paints = recorder.getPaints(); @@ -407,14 +405,10 @@ void DisplayListRenderer::reset() { } mBitmapResources.clear(); - for (size_t i = 0; i < mShaderResources.size(); i++) { - SkiaShader* resource = mShaderResources.itemAt(i); - caches.resourceCache.decrementRefcount(resource); - } - mShaderResources.clear(); - mPaints.clear(); mPaintMap.clear(); + mShaders.clear(); + mShaderMap.clear(); mMatrices.clear(); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index cc52309..112e455 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -206,11 +206,11 @@ private: PathHeap* mPathHeap; Vector mBitmapResources; - Vector mShaderResources; Vector mFilterResources; Vector mPaints; Vector mMatrices; + Vector mShaders; mutable SkFlattenableReadBuffer mReader; @@ -291,8 +291,8 @@ public: return mBitmapResources; } - const Vector& getShaderResources() const { - return mShaderResources; + const Vector& getShaders() const { + return mShaders; } const Vector& getPaints() const { @@ -366,12 +366,12 @@ private: } inline void addPaint(SkPaint* paint) { - if (paint == NULL) { + if (!paint) { addInt((int) NULL); return; } - SkPaint *paintCopy = mPaintMap.valueFor(paint); + SkPaint* paintCopy = mPaintMap.valueFor(paint); if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { paintCopy = new SkPaint(*paint); mPaintMap.add(paint, paintCopy); @@ -406,10 +406,20 @@ private: } inline void addShader(SkiaShader* shader) { - addInt((int) shader); - mShaderResources.add(shader); - Caches& caches = Caches::getInstance(); - caches.resourceCache.incrementRefcount(shader); + if (!shader) { + addInt((int) NULL); + return; + } + + SkiaShader* shaderCopy = mShaderMap.valueFor(shader); + // TODO: We also need to handle generation ID changes in compose shaders + if (!shaderCopy || shaderCopy->getGenerationId() != shader->getGenerationId()) { + shaderCopy = shader->copy(); + mShaderMap.add(shader, shaderCopy); + mShaders.add(shader); + } + + addInt((int) shaderCopy); } inline void addColorFilter(SkiaColorFilter* colorFilter) { @@ -422,11 +432,14 @@ private: SkChunkAlloc mHeap; Vector mBitmapResources; - Vector mShaderResources; Vector mFilterResources; Vector mPaints; DefaultKeyedVector mPaintMap; + + Vector mShaders; + DefaultKeyedVector mShaderMap; + Vector mMatrices; PathHeap* mPathHeap; diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 590a9d7..a1783df 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -47,10 +47,22 @@ static const GLint gTileModes[] = { // Base shader /////////////////////////////////////////////////////////////////////////////// +void SkiaShader::copyFrom(const SkiaShader& shader) { + mType = shader.mType; + mKey = shader.mKey; + mTileX = shader.mTileX; + mTileY = shader.mTileY; + mBlend = shader.mBlend; + mUnitMatrix = shader.mUnitMatrix; + mShaderMatrix = shader.mShaderMatrix; + mGenerationId = shader.mGenerationId; +} + SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix, bool blend): mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) { setMatrix(matrix); + mGenerationId = 0; } SkiaShader::~SkiaShader() { @@ -90,6 +102,13 @@ SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::Ti updateLocalMatrix(matrix); } +SkiaShader* SkiaBitmapShader::copy() { + SkiaBitmapShader* copy = new SkiaBitmapShader(); + copy->copyFrom(*this); + copy->mBitmap = mBitmap; + return copy; +} + void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { Texture* texture = mTextureCache->get(mBitmap); if (!texture) return; @@ -183,6 +202,16 @@ SkiaLinearGradientShader::~SkiaLinearGradientShader() { delete[] mPositions; } +SkiaShader* SkiaLinearGradientShader::copy() { + SkiaLinearGradientShader* copy = new SkiaLinearGradientShader(); + copy->copyFrom(*this); + copy->mBounds = mBounds; + copy->mColors = mColors; + copy->mPositions = mPositions; + copy->mCount = mCount; + return copy; +} + void SkiaLinearGradientShader::describe(ProgramDescription& description, const Extensions& extensions) { description.hasGradient = true; @@ -238,6 +267,15 @@ SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float r updateLocalMatrix(matrix); } +SkiaShader* SkiaCircularGradientShader::copy() { + SkiaCircularGradientShader* copy = new SkiaCircularGradientShader(); + copy->copyFrom(*this); + copy->mColors = mColors; + copy->mPositions = mPositions; + copy->mCount = mCount; + return copy; +} + void SkiaCircularGradientShader::describe(ProgramDescription& description, const Extensions& extensions) { description.hasGradient = true; @@ -276,6 +314,15 @@ SkiaSweepGradientShader::~SkiaSweepGradientShader() { delete[] mPositions; } +SkiaShader* SkiaSweepGradientShader::copy() { + SkiaSweepGradientShader* copy = new SkiaSweepGradientShader(); + copy->copyFrom(*this); + copy->mColors = mColors; + copy->mPositions = mPositions; + copy->mCount = mCount; + return copy; +} + void SkiaSweepGradientShader::describe(ProgramDescription& description, const Extensions& extensions) { description.hasGradient = true; @@ -318,6 +365,15 @@ SkiaComposeShader::SkiaComposeShader(SkiaShader* first, SkiaShader* second, NULL, first->blend() || second->blend()), mFirst(first), mSecond(second), mMode(mode) { } +SkiaShader* SkiaComposeShader::copy() { + SkiaComposeShader* copy = new SkiaComposeShader(); + copy->copyFrom(*this); + copy->mFirst = mFirst; + copy->mSecond = mSecond; + copy->mMode = mMode; + return copy; +} + void SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) { SkiaShader::set(textureCache, gradientCache); mFirst->set(textureCache, gradientCache); diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 6702129..1ebde38 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -56,6 +56,9 @@ struct SkiaShader { SkMatrix* matrix, bool blend); virtual ~SkiaShader(); + virtual SkiaShader* copy() = 0; + void copyFrom(const SkiaShader& shader); + virtual void describe(ProgramDescription& description, const Extensions& extensions); virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, GLuint* textureUnit); @@ -81,8 +84,13 @@ struct SkiaShader { const Snapshot& snapshot) { } + uint32_t getGenerationId() { + return mGenerationId; + } + void setMatrix(SkMatrix* matrix) { updateLocalMatrix(matrix); + mGenerationId++; } void updateLocalMatrix(const SkMatrix* matrix) { @@ -97,6 +105,9 @@ struct SkiaShader { void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); protected: + SkiaShader() { + } + /** * The appropriate texture unit must have been activated prior to invoking * this method. @@ -114,6 +125,9 @@ protected: mat4 mUnitMatrix; mat4 mShaderMatrix; + +private: + uint32_t mGenerationId; }; // struct SkiaShader @@ -127,6 +141,7 @@ protected: struct SkiaBitmapShader: public SkiaShader { SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix, bool blend); + SkiaShader* copy(); void describe(ProgramDescription& description, const Extensions& extensions); void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, @@ -134,6 +149,9 @@ struct SkiaBitmapShader: public SkiaShader { void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); private: + SkiaBitmapShader() { + } + /** * This method does not work for n == 0. */ @@ -154,6 +172,7 @@ struct SkiaLinearGradientShader: public SkiaShader { SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); ~SkiaLinearGradientShader(); + SkiaShader* copy(); void describe(ProgramDescription& description, const Extensions& extensions); void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, @@ -161,6 +180,9 @@ struct SkiaLinearGradientShader: public SkiaShader { void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); private: + SkiaLinearGradientShader() { + } + float* mBounds; uint32_t* mColors; float* mPositions; @@ -174,6 +196,7 @@ struct SkiaSweepGradientShader: public SkiaShader { SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend); ~SkiaSweepGradientShader(); + SkiaShader* copy(); virtual void describe(ProgramDescription& description, const Extensions& extensions); void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, @@ -183,6 +206,8 @@ struct SkiaSweepGradientShader: public SkiaShader { protected: SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); + SkiaSweepGradientShader() { + } uint32_t* mColors; float* mPositions; @@ -195,8 +220,13 @@ protected: struct SkiaCircularGradientShader: public SkiaSweepGradientShader { SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions, int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); + SkiaShader* copy(); void describe(ProgramDescription& description, const Extensions& extensions); + +private: + SkiaCircularGradientShader() { + } }; // struct SkiaCircularGradientShader /** @@ -204,6 +234,7 @@ struct SkiaCircularGradientShader: public SkiaSweepGradientShader { */ struct SkiaComposeShader: public SkiaShader { SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key); + SkiaShader* copy(); void set(TextureCache* textureCache, GradientCache* gradientCache); @@ -212,6 +243,9 @@ struct SkiaComposeShader: public SkiaShader { GLuint* textureUnit); private: + SkiaComposeShader() { + } + SkiaShader* mFirst; SkiaShader* mSecond; SkXfermode::Mode mMode; -- cgit v1.1