diff options
author | Romain Guy <romainguy@google.com> | 2013-03-20 19:15:02 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-03-20 19:16:53 -0700 |
commit | c5cbee7d78513527e89450e6369a30a04b2d5e7a (patch) | |
tree | a3709dd93124509c4490b889622b277d11fbef30 | |
parent | 9eac52698b18d089e73c7ec2bf73a64a39504733 (diff) | |
download | frameworks_base-c5cbee7d78513527e89450e6369a30a04b2d5e7a.zip frameworks_base-c5cbee7d78513527e89450e6369a30a04b2d5e7a.tar.gz frameworks_base-c5cbee7d78513527e89450e6369a30a04b2d5e7a.tar.bz2 |
Stop worker threads on memory trim & fix bad pointer access
Change-Id: I6fe7e31aeb6dd41fa65ab952caed97bc2da510d7
-rw-r--r-- | libs/hwui/Caches.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/PathCache.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/PathCache.h | 16 | ||||
-rw-r--r-- | libs/hwui/thread/TaskManager.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/thread/TaskManager.h | 6 | ||||
-rw-r--r-- | libs/hwui/utils/Pair.h | 58 |
6 files changed, 86 insertions, 8 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index dc3a4e2..57d1a4f 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -310,6 +310,7 @@ void Caches::flush(FlushMode mode) { fontRenderer->flush(); textureCache.flush(); pathCache.clear(); + tasks.stop(); // fall through case kFlushMode_Layers: layerCache.clear(); diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 490c22a..07c4207 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -347,14 +347,15 @@ void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) { // Paths /////////////////////////////////////////////////////////////////////////////// -void PathCache::remove(SkPath* path) { +void PathCache::remove(const path_pair_t& pair) { Vector<PathDescription> pathsToRemove; LruCache<PathDescription, PathTexture*>::Iterator i(mCache); while (i.next()) { const PathDescription& key = i.key(); if (key.type == kShapePath && - (key.shape.path.mPath == path || key.shape.path.mPath == path->getSourcePath())) { + (key.shape.path.mPath == pair.getFirst() || + key.shape.path.mPath == pair.getSecond())) { pathsToRemove.push(key); } } @@ -366,7 +367,7 @@ void PathCache::remove(SkPath* path) { void PathCache::removeDeferred(SkPath* path) { Mutex::Autolock l(mLock); - mGarbage.push(path); + mGarbage.push(path_pair_t(path, const_cast<SkPath*>(path->getSourcePath()))); } void PathCache::clearGarbage() { diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index e6d92df..1467231 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -26,6 +26,7 @@ #include "Debug.h" #include "Properties.h" #include "Texture.h" +#include "utils/Pair.h" class SkBitmap; class SkCanvas; @@ -215,10 +216,6 @@ public: PathTexture* get(SkPath* path, SkPaint* paint); /** - * Removes an entry. - */ - void remove(SkPath* path); - /** * Removes the specified path. This is meant to be called from threads * that are not the EGL context thread. */ @@ -251,6 +248,8 @@ public: float& left, float& top, float& offset, uint32_t& width, uint32_t& height); private: + typedef Pair<SkPath*, SkPath*> path_pair_t; + PathTexture* addTexture(const PathDescription& entry, const SkPath *path, const SkPaint* paint); PathTexture* addTexture(const PathDescription& entry, SkBitmap* bitmap); @@ -261,6 +260,12 @@ private: } /** + * Removes an entry. + * The pair must define first=path, second=sourcePath + */ + void remove(const path_pair_t& pair); + + /** * Ensures there is enough space in the cache for a texture of the specified * dimensions. */ @@ -318,7 +323,8 @@ private: bool mDebugEnabled; sp<PathProcessor> mProcessor; - Vector<SkPath*> mGarbage; + + Vector<path_pair_t> mGarbage; mutable Mutex mLock; }; // class PathCache diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp index ce6c8c0..c8bfd9c 100644 --- a/libs/hwui/thread/TaskManager.cpp +++ b/libs/hwui/thread/TaskManager.cpp @@ -48,6 +48,12 @@ bool TaskManager::canRunTasks() const { return mThreads.size() > 0; } +void TaskManager::stop() { + for (size_t i = 0; i < mThreads.size(); i++) { + mThreads[i]->exit(); + } +} + bool TaskManager::addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor) { if (mThreads.size() > 0) { TaskWrapper wrapper(task, processor); diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index bc86062..477314b 100644 --- a/libs/hwui/thread/TaskManager.h +++ b/libs/hwui/thread/TaskManager.h @@ -47,6 +47,12 @@ public: */ bool canRunTasks() const; + /** + * Stops all allocated threads. Adding tasks will start + * the threads again as necessary. + */ + void stop(); + private: template <typename T> friend class TaskProcessor; diff --git a/libs/hwui/utils/Pair.h b/libs/hwui/utils/Pair.h new file mode 100644 index 0000000..172606a --- /dev/null +++ b/libs/hwui/utils/Pair.h @@ -0,0 +1,58 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_PAIR_H +#define ANDROID_HWUI_PAIR_H + +namespace android { +namespace uirenderer { + +template <typename F, typename S> +struct Pair { + F first; + S second; + + Pair() { } + Pair(const Pair& o) : first(o.first), second(o.second) { } + Pair(const F& f, const S& s) : first(f), second(s) { } + + inline const F& getFirst() const { + return first; + } + + inline const S& getSecond() const { + return second; + } +}; + +}; // namespace uirenderer + +template <typename F, typename S> +struct trait_trivial_ctor< uirenderer::Pair<F, S> > +{ enum { value = aggregate_traits<F, S>::has_trivial_ctor }; }; +template <typename F, typename S> +struct trait_trivial_dtor< uirenderer::Pair<F, S> > +{ enum { value = aggregate_traits<F, S>::has_trivial_dtor }; }; +template <typename F, typename S> +struct trait_trivial_copy< uirenderer::Pair<F, S> > +{ enum { value = aggregate_traits<F, S>::has_trivial_copy }; }; +template <typename F, typename S> +struct trait_trivial_move< uirenderer::Pair<F, S> > +{ enum { value = aggregate_traits<F, S>::has_trivial_move }; }; + +}; // namespace android + +#endif // ANDROID_HWUI_PAIR_H |