Loading libs/hwui/DisplayListRenderer.cpp +53 −40 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ void DisplayList::clearResources() { delete mTransformMatrix3D; delete mStaticMatrix; delete mAnimationMatrix; mTransformMatrix = NULL; mTransformCamera = NULL; mTransformMatrix3D = NULL; Loading @@ -156,50 +157,54 @@ void DisplayList::clearResources() { mAnimationMatrix = NULL; Caches& caches = Caches::getInstance(); caches.resourceCache.lock(); for (size_t i = 0; i < mBitmapResources.size(); i++) { caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); caches.resourceCache.decrementRefcount(bitmap); caches.resourceCache.destructor(bitmap); caches.resourceCache.decrementRefcountLocked(bitmap); caches.resourceCache.destructorLocked(bitmap); } mOwnedBitmapResources.clear(); for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); } mFilterResources.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); caches.resourceCache.destructor(mShaders.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); caches.resourceCache.destructorLocked(mShaders.itemAt(i)); } mShaders.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); } caches.resourceCache.unlock(); for (size_t i = 0; i < mPaints.size(); i++) { delete mPaints.itemAt(i); } mPaints.clear(); for (size_t i = 0; i < mPaths.size(); i++) { SkPath* path = mPaths.itemAt(i); caches.pathCache.remove(path); delete path; } mPaths.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); } mSourcePaths.clear(); for (size_t i = 0; i < mMatrices.size(); i++) { delete mMatrices.itemAt(i); } mBitmapResources.clear(); mOwnedBitmapResources.clear(); mFilterResources.clear(); mShaders.clear(); mSourcePaths.clear(); mPaints.clear(); mPaths.clear(); mMatrices.clear(); } Loading @@ -223,35 +228,44 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde mReader.setMemory(buffer, mSize); Caches& caches = Caches::getInstance(); caches.resourceCache.lock(); const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources(); for (size_t i = 0; i < bitmapResources.size(); i++) { SkBitmap* resource = bitmapResources.itemAt(i); mBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources(); for (size_t i = 0; i < ownedBitmapResources.size(); i++) { SkBitmap* resource = ownedBitmapResources.itemAt(i); mOwnedBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources(); for (size_t i = 0; i < filterResources.size(); i++) { SkiaColorFilter* resource = filterResources.itemAt(i); mFilterResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkiaShader*>& shaders = recorder.getShaders(); for (size_t i = 0; i < shaders.size(); i++) { SkiaShader* resource = shaders.itemAt(i); mShaders.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); for (size_t i = 0; i < sourcePaths.size(); i++) { mSourcePaths.add(sourcePaths.itemAt(i)); caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i)); } caches.resourceCache.unlock(); const Vector<SkPaint*>& paints = recorder.getPaints(); for (size_t i = 0; i < paints.size(); i++) { mPaints.add(paints.itemAt(i)); Loading @@ -262,12 +276,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde mPaths.add(paths.itemAt(i)); } const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); for (size_t i = 0; i < sourcePaths.size(); i++) { mSourcePaths.add(sourcePaths.itemAt(i)); caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i)); } const Vector<SkMatrix*>& matrices = recorder.getMatrices(); for (size_t i = 0; i < matrices.size(); i++) { mMatrices.add(matrices.itemAt(i)); Loading Loading @@ -1309,7 +1317,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag // Base structure /////////////////////////////////////////////////////////////////////////////// DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE), DisplayListRenderer::DisplayListRenderer(): mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE), mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) { } Loading @@ -1320,34 +1329,38 @@ DisplayListRenderer::~DisplayListRenderer() { void DisplayListRenderer::reset() { mWriter.reset(); Caches& caches = Caches::getInstance(); mCaches.resourceCache.lock(); for (size_t i = 0; i < mBitmapResources.size(); i++) { caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); caches.resourceCache.decrementRefcount(bitmap); mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i)); } mOwnedBitmapResources.clear(); for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); } mFilterResources.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); } mShaders.clear(); mShaderMap.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); } mCaches.resourceCache.unlock(); mBitmapResources.clear(); mOwnedBitmapResources.clear(); mFilterResources.clear(); mSourcePaths.clear(); mShaders.clear(); mShaderMap.clear(); mPaints.clear(); mPaintMap.clear(); Loading libs/hwui/DisplayListRenderer.h +8 −7 Original line number Diff line number Diff line Loading @@ -763,7 +763,7 @@ private: mPaths.add(pathCopy); } if (mSourcePaths.indexOf(path) < 0) { Caches::getInstance().resourceCache.incrementRefcount(path); mCaches.resourceCache.incrementRefcount(path); mSourcePaths.add(path); } Loading Loading @@ -811,13 +811,13 @@ private: // which doesn't seem worth the extra cycles for this unlikely case. addInt((int) bitmap); mBitmapResources.add(bitmap); Caches::getInstance().resourceCache.incrementRefcount(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); } void addBitmapData(SkBitmap* bitmap) { addInt((int) bitmap); mOwnedBitmapResources.add(bitmap); Caches::getInstance().resourceCache.incrementRefcount(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); } inline void addShader(SkiaShader* shader) { Loading @@ -833,7 +833,7 @@ private: // replaceValueFor() performs an add if the entry doesn't exist mShaderMap.replaceValueFor(shader, shaderCopy); mShaders.add(shaderCopy); Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); mCaches.resourceCache.incrementRefcount(shaderCopy); } addInt((int) shaderCopy); Loading @@ -842,7 +842,7 @@ private: inline void addColorFilter(SkiaColorFilter* colorFilter) { addInt((int) colorFilter); mFilterResources.add(colorFilter); Caches::getInstance().resourceCache.incrementRefcount(colorFilter); mCaches.resourceCache.incrementRefcount(colorFilter); } Vector<SkBitmap*> mBitmapResources; Loading @@ -862,15 +862,16 @@ private: Vector<SkMatrix*> mMatrices; SkWriter32 mWriter; uint32_t mBufferSize; int mRestoreSaveCount; Caches& mCaches; SkWriter32 mWriter; float mTranslateX; float mTranslateY; bool mHasTranslate; bool mHasDrawOps; friend class DisplayList; Loading libs/hwui/ResourceCache.cpp +103 −27 Original line number Diff line number Diff line Loading @@ -46,15 +46,17 @@ ResourceCache::~ResourceCache() { delete mCache; } void ResourceCache::lock() { mLock.lock(); } void ResourceCache::unlock() { mLock.unlock(); } void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) { Mutex::Autolock _l(mLock); ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL || mCache->size() == 0) { ref = new ResourceReference(resourceType); mCache->add(resource, ref); } ref->refCount++; incrementRefcountLocked(resource, resourceType); } void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { Loading @@ -77,18 +79,39 @@ void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) { incrementRefcount((void*) filterResource, kColorFilter); } void ResourceCache::decrementRefcount(void* resource) { Mutex::Autolock _l(mLock); void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { // Should not get here - shouldn't get a call to decrement if we're not yet tracking it return; if (ref == NULL || mCache->size() == 0) { ref = new ResourceReference(resourceType); mCache->add(resource, ref); } ref->refCount--; if (ref->refCount == 0) { deleteResourceReference(resource, ref); ref->refCount++; } void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) { SkSafeRef(bitmapResource->pixelRef()); SkSafeRef(bitmapResource->getColorTable()); incrementRefcountLocked((void*) bitmapResource, kBitmap); } void ResourceCache::incrementRefcountLocked(SkPath* pathResource) { incrementRefcountLocked((void*) pathResource, kPath); } void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) { SkSafeRef(shaderResource->getSkShader()); incrementRefcountLocked((void*) shaderResource, kShader); } void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) { SkSafeRef(filterResource->getSkColorFilter()); incrementRefcountLocked((void*) filterResource, kColorFilter); } void ResourceCache::decrementRefcount(void* resource) { Mutex::Autolock _l(mLock); decrementRefcountLocked(resource); } void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) { Loading @@ -111,27 +134,45 @@ void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) { decrementRefcount((void*) filterResource); } void ResourceCache::recycle(SkBitmap* resource) { Mutex::Autolock _l(mLock); void ResourceCache::decrementRefcountLocked(void* resource) { ssize_t index = mCache->indexOfKey(resource); if (index < 0) { // not tracking this resource; just recycle the pixel data resource->setPixels(NULL, NULL); return; } ResourceReference* ref = mCache->valueAt(index); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { // Should not get here - shouldn't get a call to recycle if we're not yet tracking it // Should not get here - shouldn't get a call to decrement if we're not yet tracking it return; } ref->recycled = true; ref->refCount--; if (ref->refCount == 0) { deleteResourceReference(resource, ref); } } void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) { SkSafeUnref(bitmapResource->pixelRef()); SkSafeUnref(bitmapResource->getColorTable()); decrementRefcountLocked((void*) bitmapResource); } void ResourceCache::decrementRefcountLocked(SkPath* pathResource) { decrementRefcountLocked((void*) pathResource); } void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) { SkSafeUnref(shaderResource->getSkShader()); decrementRefcountLocked((void*) shaderResource); } void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) { SkSafeUnref(filterResource->getSkColorFilter()); decrementRefcountLocked((void*) filterResource); } void ResourceCache::destructor(SkPath* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkPath* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -150,6 +191,10 @@ void ResourceCache::destructor(SkPath* resource) { void ResourceCache::destructor(SkBitmap* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkBitmap* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -168,6 +213,10 @@ void ResourceCache::destructor(SkBitmap* resource) { void ResourceCache::destructor(SkiaShader* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkiaShader* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -183,6 +232,10 @@ void ResourceCache::destructor(SkiaShader* resource) { void ResourceCache::destructor(SkiaColorFilter* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkiaColorFilter* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -196,6 +249,29 @@ void ResourceCache::destructor(SkiaColorFilter* resource) { } } void ResourceCache::recycle(SkBitmap* resource) { Mutex::Autolock _l(mLock); recycleLocked(resource); } void ResourceCache::recycleLocked(SkBitmap* resource) { ssize_t index = mCache->indexOfKey(resource); if (index < 0) { // not tracking this resource; just recycle the pixel data resource->setPixels(NULL, NULL); return; } ResourceReference* ref = mCache->valueAt(index); if (ref == NULL) { // Should not get here - shouldn't get a call to recycle if we're not yet tracking it return; } ref->recycled = true; if (ref->refCount == 0) { deleteResourceReference(resource, ref); } } /** * This method should only be called while the mLock mutex is held (that mutex is grabbed * by the various destructor() and recycle() methods which call this method). Loading libs/hwui/ResourceCache.h +37 −4 Original line number Diff line number Diff line Loading @@ -52,28 +52,59 @@ public: }; class ANDROID_API ResourceCache { KeyedVector<void *, ResourceReference *>* mCache; public: ResourceCache(); ~ResourceCache(); /** * When using these two methods, make sure to only invoke the *Locked() * variants of increment/decrementRefcount(), recyle() and destructor() */ void lock(); void unlock(); void incrementRefcount(SkPath* resource); void incrementRefcount(SkBitmap* resource); void incrementRefcount(SkiaShader* resource); void incrementRefcount(SkiaColorFilter* resource); void incrementRefcount(const void* resource, ResourceType resourceType); void decrementRefcount(void* resource); void incrementRefcountLocked(SkPath* resource); void incrementRefcountLocked(SkBitmap* resource); void incrementRefcountLocked(SkiaShader* resource); void incrementRefcountLocked(SkiaColorFilter* resource); void decrementRefcount(SkBitmap* resource); void decrementRefcount(SkPath* resource); void decrementRefcount(SkiaShader* resource); void decrementRefcount(SkiaColorFilter* resource); void recycle(SkBitmap* resource); void decrementRefcountLocked(SkBitmap* resource); void decrementRefcountLocked(SkPath* resource); void decrementRefcountLocked(SkiaShader* resource); void decrementRefcountLocked(SkiaColorFilter* resource); void destructor(SkPath* resource); void destructor(SkBitmap* resource); void destructor(SkiaShader* resource); void destructor(SkiaColorFilter* resource); void destructorLocked(SkPath* resource); void destructorLocked(SkBitmap* resource); void destructorLocked(SkiaShader* resource); void destructorLocked(SkiaColorFilter* resource); void recycle(SkBitmap* resource); void recycleLocked(SkBitmap* resource); private: void deleteResourceReference(void* resource, ResourceReference* ref); void incrementRefcount(void* resource, ResourceType resourceType); void incrementRefcountLocked(void* resource, ResourceType resourceType); void decrementRefcount(void* resource); void decrementRefcountLocked(void* resource); void logCache(); /** Loading @@ -82,6 +113,8 @@ private: * or a reference queue finalization thread. */ mutable Mutex mLock; KeyedVector<void*, ResourceReference*>* mCache; }; }; // namespace uirenderer Loading Loading
libs/hwui/DisplayListRenderer.cpp +53 −40 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ void DisplayList::clearResources() { delete mTransformMatrix3D; delete mStaticMatrix; delete mAnimationMatrix; mTransformMatrix = NULL; mTransformCamera = NULL; mTransformMatrix3D = NULL; Loading @@ -156,50 +157,54 @@ void DisplayList::clearResources() { mAnimationMatrix = NULL; Caches& caches = Caches::getInstance(); caches.resourceCache.lock(); for (size_t i = 0; i < mBitmapResources.size(); i++) { caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); caches.resourceCache.decrementRefcount(bitmap); caches.resourceCache.destructor(bitmap); caches.resourceCache.decrementRefcountLocked(bitmap); caches.resourceCache.destructorLocked(bitmap); } mOwnedBitmapResources.clear(); for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); } mFilterResources.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); caches.resourceCache.destructor(mShaders.itemAt(i)); caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); caches.resourceCache.destructorLocked(mShaders.itemAt(i)); } mShaders.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); } caches.resourceCache.unlock(); for (size_t i = 0; i < mPaints.size(); i++) { delete mPaints.itemAt(i); } mPaints.clear(); for (size_t i = 0; i < mPaths.size(); i++) { SkPath* path = mPaths.itemAt(i); caches.pathCache.remove(path); delete path; } mPaths.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); } mSourcePaths.clear(); for (size_t i = 0; i < mMatrices.size(); i++) { delete mMatrices.itemAt(i); } mBitmapResources.clear(); mOwnedBitmapResources.clear(); mFilterResources.clear(); mShaders.clear(); mSourcePaths.clear(); mPaints.clear(); mPaths.clear(); mMatrices.clear(); } Loading @@ -223,35 +228,44 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde mReader.setMemory(buffer, mSize); Caches& caches = Caches::getInstance(); caches.resourceCache.lock(); const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources(); for (size_t i = 0; i < bitmapResources.size(); i++) { SkBitmap* resource = bitmapResources.itemAt(i); mBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources(); for (size_t i = 0; i < ownedBitmapResources.size(); i++) { SkBitmap* resource = ownedBitmapResources.itemAt(i); mOwnedBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources(); for (size_t i = 0; i < filterResources.size(); i++) { SkiaColorFilter* resource = filterResources.itemAt(i); mFilterResources.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const Vector<SkiaShader*>& shaders = recorder.getShaders(); for (size_t i = 0; i < shaders.size(); i++) { SkiaShader* resource = shaders.itemAt(i); mShaders.add(resource); caches.resourceCache.incrementRefcount(resource); caches.resourceCache.incrementRefcountLocked(resource); } const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); for (size_t i = 0; i < sourcePaths.size(); i++) { mSourcePaths.add(sourcePaths.itemAt(i)); caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i)); } caches.resourceCache.unlock(); const Vector<SkPaint*>& paints = recorder.getPaints(); for (size_t i = 0; i < paints.size(); i++) { mPaints.add(paints.itemAt(i)); Loading @@ -262,12 +276,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde mPaths.add(paths.itemAt(i)); } const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); for (size_t i = 0; i < sourcePaths.size(); i++) { mSourcePaths.add(sourcePaths.itemAt(i)); caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i)); } const Vector<SkMatrix*>& matrices = recorder.getMatrices(); for (size_t i = 0; i < matrices.size(); i++) { mMatrices.add(matrices.itemAt(i)); Loading Loading @@ -1309,7 +1317,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag // Base structure /////////////////////////////////////////////////////////////////////////////// DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE), DisplayListRenderer::DisplayListRenderer(): mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE), mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) { } Loading @@ -1320,34 +1329,38 @@ DisplayListRenderer::~DisplayListRenderer() { void DisplayListRenderer::reset() { mWriter.reset(); Caches& caches = Caches::getInstance(); mCaches.resourceCache.lock(); for (size_t i = 0; i < mBitmapResources.size(); i++) { caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); caches.resourceCache.decrementRefcount(bitmap); mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i)); } mOwnedBitmapResources.clear(); for (size_t i = 0; i < mFilterResources.size(); i++) { caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); } mFilterResources.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); } mShaders.clear(); mShaderMap.clear(); for (size_t i = 0; i < mSourcePaths.size(); i++) { caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); } mCaches.resourceCache.unlock(); mBitmapResources.clear(); mOwnedBitmapResources.clear(); mFilterResources.clear(); mSourcePaths.clear(); mShaders.clear(); mShaderMap.clear(); mPaints.clear(); mPaintMap.clear(); Loading
libs/hwui/DisplayListRenderer.h +8 −7 Original line number Diff line number Diff line Loading @@ -763,7 +763,7 @@ private: mPaths.add(pathCopy); } if (mSourcePaths.indexOf(path) < 0) { Caches::getInstance().resourceCache.incrementRefcount(path); mCaches.resourceCache.incrementRefcount(path); mSourcePaths.add(path); } Loading Loading @@ -811,13 +811,13 @@ private: // which doesn't seem worth the extra cycles for this unlikely case. addInt((int) bitmap); mBitmapResources.add(bitmap); Caches::getInstance().resourceCache.incrementRefcount(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); } void addBitmapData(SkBitmap* bitmap) { addInt((int) bitmap); mOwnedBitmapResources.add(bitmap); Caches::getInstance().resourceCache.incrementRefcount(bitmap); mCaches.resourceCache.incrementRefcount(bitmap); } inline void addShader(SkiaShader* shader) { Loading @@ -833,7 +833,7 @@ private: // replaceValueFor() performs an add if the entry doesn't exist mShaderMap.replaceValueFor(shader, shaderCopy); mShaders.add(shaderCopy); Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); mCaches.resourceCache.incrementRefcount(shaderCopy); } addInt((int) shaderCopy); Loading @@ -842,7 +842,7 @@ private: inline void addColorFilter(SkiaColorFilter* colorFilter) { addInt((int) colorFilter); mFilterResources.add(colorFilter); Caches::getInstance().resourceCache.incrementRefcount(colorFilter); mCaches.resourceCache.incrementRefcount(colorFilter); } Vector<SkBitmap*> mBitmapResources; Loading @@ -862,15 +862,16 @@ private: Vector<SkMatrix*> mMatrices; SkWriter32 mWriter; uint32_t mBufferSize; int mRestoreSaveCount; Caches& mCaches; SkWriter32 mWriter; float mTranslateX; float mTranslateY; bool mHasTranslate; bool mHasDrawOps; friend class DisplayList; Loading
libs/hwui/ResourceCache.cpp +103 −27 Original line number Diff line number Diff line Loading @@ -46,15 +46,17 @@ ResourceCache::~ResourceCache() { delete mCache; } void ResourceCache::lock() { mLock.lock(); } void ResourceCache::unlock() { mLock.unlock(); } void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) { Mutex::Autolock _l(mLock); ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL || mCache->size() == 0) { ref = new ResourceReference(resourceType); mCache->add(resource, ref); } ref->refCount++; incrementRefcountLocked(resource, resourceType); } void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) { Loading @@ -77,18 +79,39 @@ void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) { incrementRefcount((void*) filterResource, kColorFilter); } void ResourceCache::decrementRefcount(void* resource) { Mutex::Autolock _l(mLock); void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { // Should not get here - shouldn't get a call to decrement if we're not yet tracking it return; if (ref == NULL || mCache->size() == 0) { ref = new ResourceReference(resourceType); mCache->add(resource, ref); } ref->refCount--; if (ref->refCount == 0) { deleteResourceReference(resource, ref); ref->refCount++; } void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) { SkSafeRef(bitmapResource->pixelRef()); SkSafeRef(bitmapResource->getColorTable()); incrementRefcountLocked((void*) bitmapResource, kBitmap); } void ResourceCache::incrementRefcountLocked(SkPath* pathResource) { incrementRefcountLocked((void*) pathResource, kPath); } void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) { SkSafeRef(shaderResource->getSkShader()); incrementRefcountLocked((void*) shaderResource, kShader); } void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) { SkSafeRef(filterResource->getSkColorFilter()); incrementRefcountLocked((void*) filterResource, kColorFilter); } void ResourceCache::decrementRefcount(void* resource) { Mutex::Autolock _l(mLock); decrementRefcountLocked(resource); } void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) { Loading @@ -111,27 +134,45 @@ void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) { decrementRefcount((void*) filterResource); } void ResourceCache::recycle(SkBitmap* resource) { Mutex::Autolock _l(mLock); void ResourceCache::decrementRefcountLocked(void* resource) { ssize_t index = mCache->indexOfKey(resource); if (index < 0) { // not tracking this resource; just recycle the pixel data resource->setPixels(NULL, NULL); return; } ResourceReference* ref = mCache->valueAt(index); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { // Should not get here - shouldn't get a call to recycle if we're not yet tracking it // Should not get here - shouldn't get a call to decrement if we're not yet tracking it return; } ref->recycled = true; ref->refCount--; if (ref->refCount == 0) { deleteResourceReference(resource, ref); } } void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) { SkSafeUnref(bitmapResource->pixelRef()); SkSafeUnref(bitmapResource->getColorTable()); decrementRefcountLocked((void*) bitmapResource); } void ResourceCache::decrementRefcountLocked(SkPath* pathResource) { decrementRefcountLocked((void*) pathResource); } void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) { SkSafeUnref(shaderResource->getSkShader()); decrementRefcountLocked((void*) shaderResource); } void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) { SkSafeUnref(filterResource->getSkColorFilter()); decrementRefcountLocked((void*) filterResource); } void ResourceCache::destructor(SkPath* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkPath* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -150,6 +191,10 @@ void ResourceCache::destructor(SkPath* resource) { void ResourceCache::destructor(SkBitmap* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkBitmap* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -168,6 +213,10 @@ void ResourceCache::destructor(SkBitmap* resource) { void ResourceCache::destructor(SkiaShader* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkiaShader* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -183,6 +232,10 @@ void ResourceCache::destructor(SkiaShader* resource) { void ResourceCache::destructor(SkiaColorFilter* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); } void ResourceCache::destructorLocked(SkiaColorFilter* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { Loading @@ -196,6 +249,29 @@ void ResourceCache::destructor(SkiaColorFilter* resource) { } } void ResourceCache::recycle(SkBitmap* resource) { Mutex::Autolock _l(mLock); recycleLocked(resource); } void ResourceCache::recycleLocked(SkBitmap* resource) { ssize_t index = mCache->indexOfKey(resource); if (index < 0) { // not tracking this resource; just recycle the pixel data resource->setPixels(NULL, NULL); return; } ResourceReference* ref = mCache->valueAt(index); if (ref == NULL) { // Should not get here - shouldn't get a call to recycle if we're not yet tracking it return; } ref->recycled = true; if (ref->refCount == 0) { deleteResourceReference(resource, ref); } } /** * This method should only be called while the mLock mutex is held (that mutex is grabbed * by the various destructor() and recycle() methods which call this method). Loading
libs/hwui/ResourceCache.h +37 −4 Original line number Diff line number Diff line Loading @@ -52,28 +52,59 @@ public: }; class ANDROID_API ResourceCache { KeyedVector<void *, ResourceReference *>* mCache; public: ResourceCache(); ~ResourceCache(); /** * When using these two methods, make sure to only invoke the *Locked() * variants of increment/decrementRefcount(), recyle() and destructor() */ void lock(); void unlock(); void incrementRefcount(SkPath* resource); void incrementRefcount(SkBitmap* resource); void incrementRefcount(SkiaShader* resource); void incrementRefcount(SkiaColorFilter* resource); void incrementRefcount(const void* resource, ResourceType resourceType); void decrementRefcount(void* resource); void incrementRefcountLocked(SkPath* resource); void incrementRefcountLocked(SkBitmap* resource); void incrementRefcountLocked(SkiaShader* resource); void incrementRefcountLocked(SkiaColorFilter* resource); void decrementRefcount(SkBitmap* resource); void decrementRefcount(SkPath* resource); void decrementRefcount(SkiaShader* resource); void decrementRefcount(SkiaColorFilter* resource); void recycle(SkBitmap* resource); void decrementRefcountLocked(SkBitmap* resource); void decrementRefcountLocked(SkPath* resource); void decrementRefcountLocked(SkiaShader* resource); void decrementRefcountLocked(SkiaColorFilter* resource); void destructor(SkPath* resource); void destructor(SkBitmap* resource); void destructor(SkiaShader* resource); void destructor(SkiaColorFilter* resource); void destructorLocked(SkPath* resource); void destructorLocked(SkBitmap* resource); void destructorLocked(SkiaShader* resource); void destructorLocked(SkiaColorFilter* resource); void recycle(SkBitmap* resource); void recycleLocked(SkBitmap* resource); private: void deleteResourceReference(void* resource, ResourceReference* ref); void incrementRefcount(void* resource, ResourceType resourceType); void incrementRefcountLocked(void* resource, ResourceType resourceType); void decrementRefcount(void* resource); void decrementRefcountLocked(void* resource); void logCache(); /** Loading @@ -82,6 +113,8 @@ private: * or a reference queue finalization thread. */ mutable Mutex mLock; KeyedVector<void*, ResourceReference*>* mCache; }; }; // namespace uirenderer Loading