diff options
Diffstat (limited to 'libs')
80 files changed, 533 insertions, 909 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 4f9af7f83fb1..9e04964e7847 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -5660,11 +5660,15 @@ const DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) con return NULL; } -void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap) const -{ +void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap, + bool ignoreAndroidPackage) const { const size_t packageCount = mPackageGroups.size(); + String16 android("android"); for (size_t i = 0; i < packageCount; i++) { const PackageGroup* packageGroup = mPackageGroups[i]; + if (ignoreAndroidPackage && android == packageGroup->name) { + continue; + } const size_t typeCount = packageGroup->types.size(); for (size_t j = 0; j < typeCount; j++) { const TypeList& typeList = packageGroup->types[j]; diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index a4100a2d44fb..751531e1b57d 100644 --- a/libs/hwui/AmbientShadow.cpp +++ b/libs/hwui/AmbientShadow.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - /** * Extra vertices for the corner for smoother corner. * Only for outer vertices. @@ -56,7 +54,6 @@ #include <math.h> #include <utils/Log.h> -#include <utils/Vector.h> #include "AmbientShadow.h" #include "ShadowTessellator.h" diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk index 38e8be907720..7b2bba138df5 100644 --- a/libs/hwui/Android.common.mk +++ b/libs/hwui/Android.common.mk @@ -1,10 +1,6 @@ # getConfig in external/skia/include/core/SkBitmap.h is deprecated. # Allow Gnu extension: in-class initializer of static 'const float' member. # DeferredLayerUpdater.h: private field 'mRenderThread' is not used. -LOCAL_CLANG_CFLAGS += \ - -Wno-deprecated-declarations \ - -Wno-gnu-static-float-init \ - -Wno-unused-private-field LOCAL_SRC_FILES := \ font/CacheTexture.cpp \ @@ -23,11 +19,11 @@ LOCAL_SRC_FILES := \ renderthread/RenderTask.cpp \ renderthread/RenderThread.cpp \ renderthread/TimeLord.cpp \ + renderthread/DirtyHistory.cpp \ thread/TaskManager.cpp \ utils/Blur.cpp \ utils/GLUtils.cpp \ utils/LinearAllocator.cpp \ - utils/SortedListImpl.cpp \ AmbientShadow.cpp \ AnimationContext.cpp \ Animator.cpp \ @@ -119,9 +115,4 @@ endif # Defaults for ATRACE_TAG and LOG_TAG for libhwui LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" LOCAL_CFLAGS += -Wall -Wno-unused-parameter -Wunreachable-code -LOCAL_CFLAGS += -ffast-math -O3 - -# b/21698669 -ifneq ($(USE_CLANG_PLATFORM_BUILD),true) - LOCAL_CFLAGS += -Werror -endif +LOCAL_CFLAGS += -ffast-math -O3 -Werror diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp index 2889d2ff0b78..7e0969916825 100644 --- a/libs/hwui/AssetAtlas.cpp +++ b/libs/hwui/AssetAtlas.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "AssetAtlas.h" #include "Caches.h" #include "Image.h" diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index aa73d44af14b..693b28eb7922 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "Caches.h" #include "GammaFontRenderer.h" diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 804f609e9a0f..049d58bcd133 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -17,11 +17,6 @@ #ifndef ANDROID_HWUI_CACHES_H #define ANDROID_HWUI_CACHES_H -#ifndef LOG_TAG - #define LOG_TAG "OpenGLRenderer" -#endif - - #include "AssetAtlas.h" #include "Dither.h" #include "Extensions.h" @@ -48,12 +43,13 @@ #include <utils/KeyedVector.h> #include <utils/Singleton.h> -#include <utils/Vector.h> #include <cutils/compiler.h> #include <SkPath.h> +#include <vector> + namespace android { namespace uirenderer { @@ -206,7 +202,7 @@ private: std::unique_ptr<TextureVertex[]> mRegionMesh; mutable Mutex mGarbageLock; - Vector<Layer*> mLayerGarbage; + std::vector<Layer*> mLayerGarbage; bool mInitialized; diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h index 160d9a8a87dd..a0b87f9cadb6 100644 --- a/libs/hwui/Canvas.h +++ b/libs/hwui/Canvas.h @@ -62,6 +62,9 @@ public: virtual int width() = 0; virtual int height() = 0; + virtual void setHighContrastText(bool highContrastText) = 0; + virtual bool isHighContrastText() = 0; + // ---------------------------------------------------------------------------- // Canvas state operations // ---------------------------------------------------------------------------- @@ -118,6 +121,7 @@ public: virtual void drawLines(const float* points, int count, const SkPaint& paint) = 0; virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) = 0; + virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0; virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) = 0; virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0; diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index f05857c43a35..9fb1e756c00d 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <SkCanvas.h> #include <utils/Trace.h> @@ -72,7 +69,7 @@ public: // NOTE: ignore empty bounds special case, since we don't merge across those ops mBounds.unionWith(state->mBounds); mAllOpsOpaque &= opaqueOverBounds; - mOps.add(OpStatePair(op, state)); + mOps.push_back(OpStatePair(op, state)); } bool intersects(const Rect& rect) { @@ -136,7 +133,7 @@ public: inline int count() const { return mOps.size(); } protected: - Vector<OpStatePair> mOps; + std::vector<OpStatePair> mOps; Rect mBounds; // union of bounds of contained ops private: bool mAllOpsOpaque; @@ -421,7 +418,7 @@ void DeferredDisplayList::addSaveLayer(OpenGLRenderer& renderer, this, op, op->getFlags(), newSaveCount); storeStateOpBarrier(renderer, op); - mSaveStack.push(newSaveCount); + mSaveStack.push_back(newSaveCount); } /** @@ -436,7 +433,7 @@ void DeferredDisplayList::addSave(OpenGLRenderer& renderer, SaveOp* op, int newS // store and replay the save operation, as it may be needed to correctly playback the clip DEFER_LOGD(" adding save barrier with new save count %d", newSaveCount); storeStateOpBarrier(renderer, op); - mSaveStack.push(newSaveCount); + mSaveStack.push_back(newSaveCount); } } @@ -459,11 +456,11 @@ void DeferredDisplayList::addRestoreToCount(OpenGLRenderer& renderer, StateOp* o resetBatchingState(); } - if (mSaveStack.isEmpty() || newSaveCount > mSaveStack.top()) { + if (mSaveStack.empty() || newSaveCount > mSaveStack.back()) { return; } - while (!mSaveStack.isEmpty() && mSaveStack.top() >= newSaveCount) mSaveStack.pop(); + while (!mSaveStack.empty() && mSaveStack.back() >= newSaveCount) mSaveStack.pop_back(); storeRestoreToCountBarrier(renderer, op, mSaveStack.size() + FLUSH_SAVE_STACK_DEPTH); } @@ -495,7 +492,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { // the merge path in those cases deferInfo.mergeable &= !recordingComplexClip(); deferInfo.opaqueOverBounds &= !recordingComplexClip() - && mSaveStack.isEmpty() + && mSaveStack.empty() && !state->mRoundRectClipState; if (CC_LIKELY(mAvoidOverdraw) && mBatches.size() && @@ -510,7 +507,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { // TODO: elegant way to reuse batches? DrawBatch* b = new DrawBatch(deferInfo); b->add(op, state, deferInfo.opaqueOverBounds); - mBatches.add(b); + mBatches.push_back(b); return; } @@ -520,12 +517,12 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { // insertion point of a new batch, will hopefully be immediately after similar batch // (eventually, should be similar shader) int insertBatchIndex = mBatches.size(); - if (!mBatches.isEmpty()) { + if (!mBatches.empty()) { if (state->mBounds.isEmpty()) { // don't know the bounds for op, so add to last batch and start from scratch on next op DrawBatch* b = new DrawBatch(deferInfo); b->add(op, state, deferInfo.opaqueOverBounds); - mBatches.add(b); + mBatches.push_back(b); resetBatchingState(); #if DEBUG_DEFER DEFER_LOGD("Warning: Encountered op with empty bounds, resetting batches"); @@ -589,7 +586,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) { DEFER_LOGD("creating %singBatch %p, bid %x, at %d", deferInfo.mergeable ? "Merg" : "Draw", targetBatch, deferInfo.batchId, insertBatchIndex); - mBatches.insertAt(targetBatch, insertBatchIndex); + mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch); } targetBatch->add(op, state, deferInfo.opaqueOverBounds); @@ -600,7 +597,7 @@ void DeferredDisplayList::storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* DeferredDisplayState* state = createState(); renderer.storeDisplayState(*state, getStateOpDeferFlags()); - mBatches.add(new StateOpBatch(op, state)); + mBatches.push_back(new StateOpBatch(op, state)); resetBatchingState(); } @@ -613,7 +610,7 @@ void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, S // doesn't have kClip_SaveFlag set DeferredDisplayState* state = createState(); renderer.storeDisplayState(*state, getStateOpDeferFlags()); - mBatches.add(new RestoreToCountBatch(op, state, newSaveCount)); + mBatches.push_back(new RestoreToCountBatch(op, state, newSaveCount)); resetBatchingState(); } @@ -621,7 +618,7 @@ void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, S // Replay / flush ///////////////////////////////////////////////////////////////////////////////// -static void replayBatchList(const Vector<Batch*>& batchList, +static void replayBatchList(const std::vector<Batch*>& batchList, OpenGLRenderer& renderer, Rect& dirty) { for (unsigned int i = 0; i < batchList.size(); i++) { @@ -667,7 +664,7 @@ void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) { // leave deferred state ops alone for simplicity (empty save restore pairs may now exist) if (mBatches[i] && mBatches[i]->purelyDrawBatch()) { delete mBatches[i]; - mBatches.replaceAt(nullptr, i); + mBatches[i] = nullptr; } } mEarliestUnclearedIndex = maxIndex + 1; diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index 160c1ad2d1f6..4f2dca5f3ee1 100644 --- a/libs/hwui/DeferredDisplayList.h +++ b/libs/hwui/DeferredDisplayList.h @@ -19,13 +19,14 @@ #include <utils/Errors.h> #include <utils/LinearAllocator.h> -#include <utils/Vector.h> #include <utils/TinyHashMap.h> #include "Matrix.h" #include "OpenGLRenderer.h" #include "Rect.h" +#include <vector> + class SkBitmap; namespace android { @@ -100,7 +101,7 @@ public: kOpBatch_Count, // Add other batch ids before this }; - bool isEmpty() { return mBatches.isEmpty(); } + bool isEmpty() { return mBatches.empty(); } /** * Plays back all of the draw ops recorded into batches to the renderer. @@ -157,10 +158,10 @@ private: * that when an associated restoreToCount is deferred, it can be recorded as a * RestoreToCountBatch */ - Vector<int> mSaveStack; + std::vector<int> mSaveStack; int mComplexClipStackStart; - Vector<Batch*> mBatches; + std::vector<Batch*> mBatches; // Maps batch ids to the most recent *non-merging* batch of that id Batch* mBatchLookup[kOpBatch_Count]; diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index a17904e31047..38f2363f3532 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -24,14 +24,13 @@ namespace android { namespace uirenderer { -DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer) +DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer) : mSurfaceTexture(nullptr) , mTransform(nullptr) , mNeedsGLContextAttach(false) , mUpdateTexImage(false) , mLayer(layer) - , mCaches(Caches::getInstance()) - , mRenderThread(thread) { + , mCaches(Caches::getInstance()) { mWidth = mLayer->layer.getWidth(); mHeight = mLayer->layer.getHeight(); mBlend = mLayer->isBlend(); diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 82f2741b7478..df7c594cf187 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -35,7 +35,7 @@ class DeferredLayerUpdater : public VirtualLightRefBase { public: // Note that DeferredLayerUpdater assumes it is taking ownership of the layer // and will not call incrementRef on it as a result. - ANDROID_API DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer); + ANDROID_API DeferredLayerUpdater(Layer* layer); ANDROID_API ~DeferredLayerUpdater(); ANDROID_API bool setSize(int width, int height) { @@ -101,7 +101,6 @@ private: Layer* mLayer; Caches& mCaches; - renderthread::RenderThread& mRenderThread; void doUpdateTexImage(); }; diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index e679bff18c86..0af9420533eb 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <SkCanvas.h> #include <algorithm> @@ -42,13 +40,13 @@ void DisplayListData::cleanupResources() { resourceCache.lock(); for (size_t i = 0; i < patchResources.size(); i++) { - resourceCache.decrementRefcountLocked(patchResources.itemAt(i)); + resourceCache.decrementRefcountLocked(patchResources[i]); } resourceCache.unlock(); for (size_t i = 0; i < pathResources.size(); i++) { - const SkPath* path = pathResources.itemAt(i); + const SkPath* path = pathResources[i]; if (path->unique() && Caches::hasInstance()) { Caches::getInstance().pathCache.removeDeferred(path); } @@ -62,8 +60,10 @@ void DisplayListData::cleanupResources() { } size_t DisplayListData::addChild(DrawRenderNodeOp* op) { - mReferenceHolders.push(op->renderNode()); - return mChildren.add(op); + mReferenceHolders.push_back(op->renderNode()); + size_t index = mChildren.size(); + mChildren.push_back(op); + return index; } }; // namespace uirenderer diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 7fbda1f6b192..0bdb8169ea06 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -17,10 +17,6 @@ #ifndef ANDROID_HWUI_DISPLAY_LIST_H #define ANDROID_HWUI_DISPLAY_LIST_H -#ifndef LOG_TAG - #define LOG_TAG "OpenGLRenderer" -#endif - #include <SkCamera.h> #include <SkMatrix.h> @@ -31,7 +27,6 @@ #include <utils/RefBase.h> #include <utils/SortedVector.h> #include <utils/String8.h> -#include <utils/Vector.h> #include <cutils/compiler.h> @@ -43,6 +38,8 @@ #include "Matrix.h" #include "RenderProperties.h" +#include <vector> + class SkBitmap; class SkPaint; class SkPath; @@ -128,28 +125,28 @@ public: ~DisplayListData(); // pointers to all ops within display list, pointing into allocator data - Vector<DisplayListOp*> displayListOps; + std::vector<DisplayListOp*> displayListOps; // index of DisplayListOp restore, after which projected descendents should be drawn int projectionReceiveIndex; - Vector<const SkBitmap*> bitmapResources; - Vector<const SkPath*> pathResources; - Vector<const Res_png_9patch*> patchResources; + std::vector<const SkBitmap*> bitmapResources; + std::vector<const SkPath*> pathResources; + std::vector<const Res_png_9patch*> patchResources; std::vector<std::unique_ptr<const SkPaint>> paints; std::vector<std::unique_ptr<const SkRegion>> regions; Vector<Functor*> functors; - const Vector<Chunk>& getChunks() const { + const std::vector<Chunk>& getChunks() const { return chunks; } size_t addChild(DrawRenderNodeOp* childOp); - const Vector<DrawRenderNodeOp*>& children() { return mChildren; } + const std::vector<DrawRenderNodeOp*>& children() { return mChildren; } void ref(VirtualLightRefBase* prop) { - mReferenceHolders.push(prop); + mReferenceHolders.push_back(prop); } size_t getUsedSize() { @@ -160,12 +157,12 @@ public: } private: - Vector< sp<VirtualLightRefBase> > mReferenceHolders; + std::vector< sp<VirtualLightRefBase> > mReferenceHolders; // list of children display lists for quick, non-drawing traversal - Vector<DrawRenderNodeOp*> mChildren; + std::vector<DrawRenderNodeOp*> mChildren; - Vector<Chunk> chunks; + std::vector<Chunk> chunks; // allocator into which all ops were allocated LinearAllocator allocator; diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index aeb1a3d0ae68..c48b070819a4 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -31,7 +31,7 @@ namespace android { namespace uirenderer { -DisplayListCanvas::DisplayListCanvas() +DisplayListCanvas::DisplayListCanvas(int width, int height) : mState(*this) , mResourceCache(ResourceCache::getInstance()) , mDisplayListData(nullptr) @@ -41,6 +41,7 @@ DisplayListCanvas::DisplayListCanvas() , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) , mRestoreSaveCount(-1) { + reset(width, height); } DisplayListCanvas::~DisplayListCanvas() { @@ -48,27 +49,12 @@ DisplayListCanvas::~DisplayListCanvas() { "Destroyed a DisplayListCanvas during a record!"); } -/////////////////////////////////////////////////////////////////////////////// -// Operations -/////////////////////////////////////////////////////////////////////////////// - -DisplayListData* DisplayListCanvas::finishRecording() { - mPaintMap.clear(); - mRegionMap.clear(); - mPathMap.clear(); - DisplayListData* data = mDisplayListData; - mDisplayListData = nullptr; - mSkiaCanvasProxy.reset(nullptr); - return data; -} - -void DisplayListCanvas::prepareDirty(float left, float top, - float right, float bottom) { - +void DisplayListCanvas::reset(int width, int height) { LOG_ALWAYS_FATAL_IF(mDisplayListData, "prepareDirty called a second time during a recording!"); mDisplayListData = new DisplayListData(); + mState.setViewport(width, height); mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; @@ -76,16 +62,22 @@ void DisplayListCanvas::prepareDirty(float left, float top, mRestoreSaveCount = -1; } -bool DisplayListCanvas::finish() { + +/////////////////////////////////////////////////////////////////////////////// +// Operations +/////////////////////////////////////////////////////////////////////////////// + +DisplayListData* DisplayListCanvas::finishRecording() { flushRestoreToCount(); flushTranslate(); - return false; -} - -void DisplayListCanvas::interrupt() { -} -void DisplayListCanvas::resume() { + mPaintMap.clear(); + mRegionMap.clear(); + mPathMap.clear(); + DisplayListData* data = mDisplayListData; + mDisplayListData = nullptr; + mSkiaCanvasProxy.reset(nullptr); + return data; } void DisplayListCanvas::callDrawGLFunction(Functor *functor) { @@ -445,16 +437,6 @@ void DisplayListCanvas::drawPosText(const uint16_t* text, const float* positions addDrawOp(op); } -static void simplifyPaint(int color, SkPaint* paint) { - paint->setColor(color); - paint->setShader(nullptr); - paint->setColorFilter(nullptr); - paint->setLooper(nullptr); - paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); - paint->setStrokeJoin(SkPaint::kRound_Join); - paint->setLooper(nullptr); -} - void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, int count, const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, @@ -467,30 +449,34 @@ void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, positions = refBuffer<float>(positions, count * 2); Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); - if (CC_UNLIKELY(mHighContrastText)) { - // high contrast draw path - int color = paint.getColor(); - int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); - bool darken = channelSum < (128 * 3); - - // outline - SkPaint* outlinePaint = copyPaint(&paint); - simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); - outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); - addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? - - // inner - SkPaint* innerPaint = copyPaint(&paint); - simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); - innerPaint->setStyle(SkPaint::kFill_Style); - addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, innerPaint, totalAdvance, bounds)); + DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, + x, y, positions, refPaint(&paint), totalAdvance, bounds); + addDrawOp(op); +} + +void DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { + if (paint.getStyle() != SkPaint::kFill_Style || + (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) { + SkRegion::Iterator it(region); + while (!it.done()) { + const SkIRect& r = it.rect(); + drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); + it.next(); + } } else { - // standard draw path - DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, - x, y, positions, refPaint(&paint), totalAdvance, bounds); - addDrawOp(op); + int count = 0; + Vector<float> rects; + SkRegion::Iterator it(region); + 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 += 4; + it.next(); + } + drawRects(rects.array(), count, &paint); } } @@ -530,11 +516,12 @@ void DisplayListCanvas::flushTranslate() { } size_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) { - int insertIndex = mDisplayListData->displayListOps.add(op); + int insertIndex = mDisplayListData->displayListOps.size(); + mDisplayListData->displayListOps.push_back(op); if (mDeferredBarrierType != kBarrier_None) { // op is first in new chunk - mDisplayListData->chunks.push(); - DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop(); + mDisplayListData->chunks.emplace_back(); + DisplayListData::Chunk& newChunk = mDisplayListData->chunks.back(); newChunk.beginOpIndex = insertIndex; newChunk.endOpIndex = insertIndex + 1; newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder); @@ -544,7 +531,7 @@ size_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) { mDeferredBarrierType = kBarrier_None; } else { // standard case - append to existing chunk - mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1; + mDisplayListData->chunks.back().endOpIndex = insertIndex + 1; } return insertIndex; } @@ -576,7 +563,7 @@ size_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) { int childIndex = mDisplayListData->addChild(op); // update the chunk's child indices - DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop(); + DisplayListData::Chunk& chunk = mDisplayListData->chunks.back(); chunk.endChildIndex = childIndex + 1; if (op->renderNode()->stagingProperties().isProjectionReceiver()) { diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h index 4982cc919b5e..f3f5713bbc3f 100644 --- a/libs/hwui/DisplayListCanvas.h +++ b/libs/hwui/DisplayListCanvas.h @@ -62,47 +62,28 @@ class StateOp; */ class ANDROID_API DisplayListCanvas: public Canvas, public CanvasStateClient { public: - DisplayListCanvas(); + DisplayListCanvas(int width, int height); virtual ~DisplayListCanvas(); - void insertReorderBarrier(bool enableReorder); + void reset(int width, int height); DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- -// HWUI Frame state operations -// ---------------------------------------------------------------------------- - - void prepareDirty(float left, float top, float right, float bottom); - void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); } - bool finish(); - void interrupt(); - void resume(); - -// ---------------------------------------------------------------------------- // HWUI Canvas state operations // ---------------------------------------------------------------------------- - void setViewport(int width, int height) { mState.setViewport(width, height); } - - const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); } - - bool isCurrentTransformSimple() { - return mState.currentTransform()->isSimple(); - } + void insertReorderBarrier(bool enableReorder); // ---------------------------------------------------------------------------- // HWUI Canvas draw operations // ---------------------------------------------------------------------------- - // Bitmap-based - void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); // TODO: move drawPatch() to Canvas.h void drawPatch(const SkBitmap& bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); // Shapes - void drawRects(const float* rects, int count, const SkPaint* paint); void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, @@ -120,10 +101,6 @@ public: // TODO: rename for consistency void callDrawGLFunction(Functor* functor); - void setHighContrastText(bool highContrastText) { - mHighContrastText = highContrastText; - } - // ---------------------------------------------------------------------------- // CanvasStateClient interface // ---------------------------------------------------------------------------- @@ -144,6 +121,11 @@ public: virtual int width() override { return mState.getWidth(); } virtual int height() override { return mState.getHeight(); } + virtual void setHighContrastText(bool highContrastText) override { + mHighContrastText = highContrastText; + } + virtual bool isHighContrastText() override { return mHighContrastText; } + // ---------------------------------------------------------------------------- // android/graphics/Canvas state operations // ---------------------------------------------------------------------------- @@ -205,6 +187,7 @@ public: } virtual void drawLines(const float* points, int count, const SkPaint& paint) override; virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override; + virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override; virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) override; virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override; @@ -249,6 +232,9 @@ private: kBarrier_OutOfOrder, }; + void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint); + void drawRects(const float* rects, int count, const SkPaint* paint); + void flushRestoreToCount(); void flushTranslate(); void flushReorderBarrier(); @@ -285,7 +271,7 @@ private: // The points/verbs within the path are refcounted so this copy operation // is inexpensive and maintains the generationID of the original path. const SkPath* cachedPath = new SkPath(*path); - mDisplayListData->pathResources.add(cachedPath); + mDisplayListData->pathResources.push_back(cachedPath); return cachedPath; } @@ -319,16 +305,6 @@ private: return cachedPaint; } - inline SkPaint* copyPaint(const SkPaint* paint) { - if (!paint) return nullptr; - - SkPaint* returnPaint = new SkPaint(*paint); - std::unique_ptr<const SkPaint> copy(returnPaint); - mDisplayListData->paints.push_back(std::move(copy)); - - return returnPaint; - } - inline const SkRegion* refRegion(const SkRegion* region) { if (!region) { return region; @@ -360,7 +336,7 @@ private: } inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { - mDisplayListData->patchResources.add(patch); + mDisplayListData->patchResources.push_back(patch); mResourceCache.incrementRefcount(patch); return patch; } diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 8b4b4ba2b79e..8ff58d4f64f5 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -139,7 +139,7 @@ public: * reducing which operations are tagged as mergeable. */ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, - const Vector<OpStatePair>& ops, const Rect& bounds) { + const std::vector<OpStatePair>& ops, const Rect& bounds) { for (unsigned int i = 0; i < ops.size(); i++) { renderer.restoreDisplayState(*(ops[i].state), true); ops[i].op->applyDraw(renderer, dirty); @@ -648,7 +648,7 @@ public: * the current layer, if any. */ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, - const Vector<OpStatePair>& ops, const Rect& bounds) override { + const std::vector<OpStatePair>& ops, const Rect& bounds) override { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -819,7 +819,7 @@ public: * is also responsible for dirtying the current layer, if any. */ virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, - const Vector<OpStatePair>& ops, const Rect& bounds) override { + const std::vector<OpStatePair>& ops, const Rect& bounds) override { const DeferredDisplayState& firstState = *(ops[0].state); renderer.restoreDisplayState(firstState, true); // restore all but the clip @@ -1358,7 +1358,7 @@ public: } virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, - const Vector<OpStatePair>& ops, const Rect& bounds) override { + const std::vector<OpStatePair>& ops, const Rect& bounds) override { for (unsigned int i = 0; i < ops.size(); i++) { const DeferredDisplayState& state = *(ops[i].state); DrawOpMode drawOpMode = (i == ops.size() - 1) ? DrawOpMode::kFlush : DrawOpMode::kDefer; diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp index d96775aa7ff1..814bada81b35 100644 --- a/libs/hwui/Extensions.cpp +++ b/libs/hwui/Extensions.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "Extensions.h" #include "Debug.h" diff --git a/libs/hwui/FboCache.cpp b/libs/hwui/FboCache.cpp index b54d53233a65..cca3cb7a98f1 100644 --- a/libs/hwui/FboCache.cpp +++ b/libs/hwui/FboCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <stdlib.h> #include "Debug.h" diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 35051b7cccea..9be8c7d45bca 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -134,7 +134,7 @@ FontRenderer::FontRenderer() sLogFontRendererCreate = false; } -void clearCacheTextures(Vector<CacheTexture*>& cacheTextures) { +void clearCacheTextures(std::vector<CacheTexture*>& cacheTextures) { for (uint32_t i = 0; i < cacheTextures.size(); i++) { delete cacheTextures[i]; } @@ -171,7 +171,7 @@ void FontRenderer::flushAllAndInvalidate() { mDrawn = false; } -void FontRenderer::flushLargeCaches(Vector<CacheTexture*>& cacheTextures) { +void FontRenderer::flushLargeCaches(std::vector<CacheTexture*>& cacheTextures) { // Start from 1; don't deallocate smallest/default texture for (uint32_t i = 1; i < cacheTextures.size(); i++) { CacheTexture* cacheTexture = cacheTextures[i]; @@ -191,7 +191,7 @@ void FontRenderer::flushLargeCaches() { flushLargeCaches(mRGBACacheTextures); } -CacheTexture* FontRenderer::cacheBitmapInTexture(Vector<CacheTexture*>& cacheTextures, +CacheTexture* FontRenderer::cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures, const SkGlyph& glyph, uint32_t* startX, uint32_t* startY) { for (uint32_t i = 0; i < cacheTextures.size(); i++) { if (cacheTextures[i]->fitBitmap(glyph, startX, startY)) { @@ -218,7 +218,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp // choose an appropriate cache texture list for this glyph format SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat); - Vector<CacheTexture*>* cacheTextures = nullptr; + std::vector<CacheTexture*>* cacheTextures = nullptr; switch (format) { case SkMask::kA8_Format: case SkMask::kBW_Format: @@ -399,17 +399,17 @@ void FontRenderer::initTextTexture() { clearCacheTextures(mRGBACacheTextures); mUploadTexture = false; - mACacheTextures.push(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, + mACacheTextures.push_back(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_ALPHA, true)); - mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, + mACacheTextures.push_back(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false)); - mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, + mACacheTextures.push_back(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false)); - mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight, + mACacheTextures.push_back(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight, GL_ALPHA, false)); - mRGBACacheTextures.push(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, + mRGBACacheTextures.push_back(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_RGBA, false)); - mRGBACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, + mRGBACacheTextures.push_back(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_RGBA, false)); mCurrentCacheTexture = mACacheTextures[0]; } @@ -425,7 +425,7 @@ void FontRenderer::checkInit() { mInitialized = true; } -void checkTextureUpdateForCache(Caches& caches, Vector<CacheTexture*>& cacheTextures, +void checkTextureUpdateForCache(Caches& caches, std::vector<CacheTexture*>& cacheTextures, bool& resetPixelStore, GLuint& lastTextureId) { for (uint32_t i = 0; i < cacheTextures.size(); i++) { CacheTexture* cacheTexture = cacheTextures[i]; @@ -470,11 +470,10 @@ void FontRenderer::checkTextureUpdate() { mUploadTexture = false; } -void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) { +void FontRenderer::issueDrawCommand(std::vector<CacheTexture*>& cacheTextures) { if (!mFunctor) return; bool first = true; - bool forceRebind = false; for (uint32_t i = 0; i < cacheTextures.size(); i++) { CacheTexture* texture = cacheTextures[i]; if (texture->canDraw()) { @@ -487,7 +486,6 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) { mFunctor->draw(*texture, mLinearFiltering); texture->resetMesh(); - forceRebind = false; } } } @@ -741,7 +739,7 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, flo Blur::vertical(gaussian.get(), intRadius, scratch.get(), *image, width, height); } -static uint32_t calculateCacheSize(const Vector<CacheTexture*>& cacheTextures) { +static uint32_t calculateCacheSize(const std::vector<CacheTexture*>& cacheTextures) { uint32_t size = 0; for (uint32_t i = 0; i < cacheTextures.size(); i++) { CacheTexture* cacheTexture = cacheTextures[i]; diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index dfb107c99bc5..2954975b1413 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -21,16 +21,16 @@ #include "font/CacheTexture.h" #include "font/CachedGlyphInfo.h" #include "font/Font.h" -#include "utils/SortedList.h" #include <utils/LruCache.h> -#include <utils/Vector.h> #include <utils/StrongPointer.h> #include <SkPaint.h> #include <GLES2/gl2.h> +#include <vector> + #ifdef ANDROID_ENABLE_RENDERSCRIPT #include "RenderScript.h" namespace RSC { @@ -75,7 +75,7 @@ public: FontRenderer(); ~FontRenderer(); - void flushLargeCaches(Vector<CacheTexture*>& cacheTextures); + void flushLargeCaches(std::vector<CacheTexture*>& cacheTextures); void flushLargeCaches(); void setGammaTable(const uint8_t* gammaTable) { @@ -127,7 +127,7 @@ private: CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate); void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, uint32_t *retOriginX, uint32_t *retOriginY, bool precaching); - CacheTexture* cacheBitmapInTexture(Vector<CacheTexture*>& cacheTextures, const SkGlyph& glyph, + CacheTexture* cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures, const SkGlyph& glyph, uint32_t* startX, uint32_t* startY); void flushAllAndInvalidate(); @@ -136,7 +136,7 @@ private: void initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor); void finishRender(); - void issueDrawCommand(Vector<CacheTexture*>& cacheTextures); + void issueDrawCommand(std::vector<CacheTexture*>& cacheTextures); void issueDrawCommand(); void appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2, float u2, float v2, @@ -164,8 +164,8 @@ private: uint32_t mLargeCacheWidth; uint32_t mLargeCacheHeight; - Vector<CacheTexture*> mACacheTextures; - Vector<CacheTexture*> mRGBACacheTextures; + std::vector<CacheTexture*> mACacheTextures; + std::vector<CacheTexture*> mRGBACacheTextures; Font* mCurrentFont; LruCache<Font::FontDescription, Font*> mActiveFonts; diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index ea93e7f9716b..aa105f9fec0a 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/JenkinsHash.h> #include "Caches.h" diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 08319ea1ec9b..7534c5d11164 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -25,7 +25,6 @@ #include <utils/LruCache.h> #include <utils/Mutex.h> -#include <utils/Vector.h> namespace android { namespace uirenderer { @@ -183,7 +182,6 @@ private: bool mUseFloatTexture; bool mHasNpot; - Vector<SkShader*> mGarbage; mutable Mutex mLock; }; // class GradientCache diff --git a/libs/hwui/Image.cpp b/libs/hwui/Image.cpp index a31c54675f8a..68a356ba1be0 100644 --- a/libs/hwui/Image.cpp +++ b/libs/hwui/Image.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/Log.h> #include "Caches.h" diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index e16865ede160..928f91bdd4d9 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "Layer.h" #include "Caches.h" diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index bcbd4129b7e7..33f40b006092 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <GLES2/gl2.h> #include <utils/Log.h> @@ -89,9 +87,8 @@ void LayerCache::deleteLayer(Layer* layer) { } void LayerCache::clear() { - size_t count = mCache.size(); - for (size_t i = 0; i < count; i++) { - deleteLayer(mCache.itemAt(i).mLayer); + for (auto entry : mCache) { + deleteLayer(entry.mLayer); } mCache.clear(); } @@ -100,11 +97,11 @@ Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uin Layer* layer = nullptr; LayerEntry entry(width, height); - ssize_t index = mCache.indexOf(entry); + auto iter = mCache.find(entry); - if (index >= 0) { - entry = mCache.itemAt(index); - mCache.removeAt(index); + if (iter != mCache.end()) { + entry = *iter; + mCache.erase(iter); layer = entry.mLayer; layer->state = Layer::kState_RemovedFromCache; @@ -131,9 +128,7 @@ Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uin } void LayerCache::dump() { - size_t size = mCache.size(); - for (size_t i = 0; i < size; i++) { - const LayerEntry& entry = mCache.itemAt(i); + for (auto entry : mCache) { ALOGD(" Layer size %dx%d", entry.mWidth, entry.mHeight); } } @@ -146,13 +141,9 @@ bool LayerCache::put(Layer* layer) { if (size < mMaxSize) { // TODO: Use an LRU while (mSize + size > mMaxSize) { - size_t position = 0; -#if LAYER_REMOVE_BIGGEST_FIRST - position = mCache.size() - 1; -#endif - Layer* victim = mCache.itemAt(position).mLayer; + Layer* victim = mCache.begin()->mLayer; deleteLayer(victim); - mCache.removeAt(position); + mCache.erase(mCache.begin()); LAYER_LOGD(" Deleting layer %.2fx%.2f", victim->layer.getWidth(), victim->layer.getHeight()); @@ -162,7 +153,7 @@ bool LayerCache::put(Layer* layer) { LayerEntry entry(layer); - mCache.add(entry); + mCache.insert(entry); mSize += size; layer->state = Layer::kState_InCache; diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h index 7d17b9ba41aa..6fe7b3aae859 100644 --- a/libs/hwui/LayerCache.h +++ b/libs/hwui/LayerCache.h @@ -19,7 +19,8 @@ #include "Debug.h" #include "Layer.h" -#include "utils/SortedList.h" + +#include <set> namespace android { namespace uirenderer { @@ -118,12 +119,8 @@ private: return compare(*this, other) != 0; } - friend inline int strictly_order_type(const LayerEntry& lhs, const LayerEntry& rhs) { - return LayerEntry::compare(lhs, rhs) < 0; - } - - friend inline int compare_type(const LayerEntry& lhs, const LayerEntry& rhs) { - return LayerEntry::compare(lhs, rhs); + bool operator<(const LayerEntry& other) const { + return LayerEntry::compare(*this, other) < 0; } Layer* mLayer; @@ -133,7 +130,7 @@ private: void deleteLayer(Layer* layer); - SortedList<LayerEntry> mCache; + std::multiset<LayerEntry> mCache; uint32_t mSize; uint32_t mMaxSize; diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp index 06e67c0e85ad..115e23c848dc 100644 --- a/libs/hwui/Matrix.cpp +++ b/libs/hwui/Matrix.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <math.h> #include <stdlib.h> #include <string.h> diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2292ef415cfc..8e04bdf3b8ad 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -419,7 +419,7 @@ void OpenGLRenderer::updateLayers() { // Note: it is very important to update the layers in order for (int i = 0; i < count; i++) { - Layer* layer = mLayerUpdates.itemAt(i).get(); + Layer* layer = mLayerUpdates[i].get(); updateLayer(layer, false); } @@ -438,7 +438,7 @@ void OpenGLRenderer::flushLayers() { // Note: it is very important to update the layers in order for (int i = 0; i < count; i++) { - mLayerUpdates.itemAt(i)->flush(); + mLayerUpdates[i]->flush(); } mLayerUpdates.clear(); @@ -455,7 +455,7 @@ void OpenGLRenderer::pushLayerUpdate(Layer* layer) { // the insertion order. The linear search is not an issue since // this list is usually very short (typically one item, at most a few) for (int i = mLayerUpdates.size() - 1; i >= 0; i--) { - if (mLayerUpdates.itemAt(i) == layer) { + if (mLayerUpdates[i] == layer) { return; } } @@ -466,8 +466,8 @@ void OpenGLRenderer::pushLayerUpdate(Layer* layer) { void OpenGLRenderer::cancelLayerUpdate(Layer* layer) { if (layer) { for (int i = mLayerUpdates.size() - 1; i >= 0; i--) { - if (mLayerUpdates.itemAt(i) == layer) { - mLayerUpdates.removeAt(i); + if (mLayerUpdates[i] == layer) { + mLayerUpdates.erase(mLayerUpdates.begin() + i); break; } } @@ -1918,7 +1918,7 @@ void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p // Mask the ripple path by the projection mask, now that it's // in local space. Note that this can create CCW paths. - Op(path, maskPath, kIntersect_PathOp, &path); + Op(path, maskPath, kIntersect_SkPathOp, &path); } drawConvexPath(path, p); } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 402f6edd475d..390f6207f4ea 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -44,12 +44,13 @@ #include <utils/Functor.h> #include <utils/RefBase.h> #include <utils/SortedVector.h> -#include <utils/Vector.h> #include <cutils/compiler.h> #include <androidfw/ResourceTypes.h> +#include <vector> + class SkShader; namespace android { @@ -855,7 +856,7 @@ private: // List of rectangles to clear after saveLayer() is invoked std::vector<Rect> mLayers; // List of layers to update at the beginning of a frame - Vector< sp<Layer> > mLayerUpdates; + std::vector< sp<Layer> > mLayerUpdates; // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in // Properties.h diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h index c98932cf095e..8d4d4f085f98 100644 --- a/libs/hwui/Outline.h +++ b/libs/hwui/Outline.h @@ -33,13 +33,29 @@ public: , mAlpha(0.0f) {} void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) { + mAlpha = alpha; + if (mType == kOutlineType_RoundRect + && left == mBounds.left + && right == mBounds.right + && top == mBounds.top + && bottom == mBounds.bottom + && radius == mRadius) { + // nothing to change, don't do any work + return; + } + mType = kOutlineType_RoundRect; mBounds.set(left, top, right, bottom); mRadius = radius; + + // update mPath to reflect new outline mPath.reset(); - mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), - radius, radius); - mAlpha = alpha; + if (MathUtils::isPositive(radius)) { + mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), + radius, radius); + } else { + mPath.addRect(left, top, right, bottom); + } } void setConvexPath(const SkPath* outline, float alpha) { diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index 6a7dfb3890d3..500f9e95381c 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <cmath> #include <utils/Log.h> @@ -208,8 +206,7 @@ void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, f // Record all non empty quads if (hasEmptyQuads) { - Rect bounds(x1, y1, x2, y2); - quads.add(bounds); + quads.emplace_back(x1, y1, x2, y2); } mUvMapper.map(u1, v1, u2, v2); diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h index b63bd24456d3..f04416ccabf9 100644 --- a/libs/hwui/Patch.h +++ b/libs/hwui/Patch.h @@ -21,13 +21,13 @@ #include <GLES2/gl2.h> -#include <utils/Vector.h> - #include <androidfw/ResourceTypes.h> #include "Rect.h" #include "UvMapper.h" +#include <vector> + namespace android { namespace uirenderer { @@ -52,7 +52,7 @@ public: uint32_t verticesCount = 0; uint32_t indexCount = 0; bool hasEmptyQuads = false; - Vector<Rect> quads; + std::vector<Rect> quads; GLintptr positionOffset = 0; GLintptr textureOffset = 0; diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index 27652624b498..98812805259e 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/JenkinsHash.h> #include <utils/Log.h> diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 3af640f76365..f503e5d6e8ba 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <SkBitmap.h> #include <SkCanvas.h> #include <SkColor.h> @@ -341,7 +338,7 @@ void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) { void PathCache::removeDeferred(const SkPath* path) { Mutex::Autolock l(mLock); - mGarbage.push(path->getGenerationID()); + mGarbage.push_back(path->getGenerationID()); } void PathCache::clearGarbage() { @@ -349,10 +346,7 @@ void PathCache::clearGarbage() { { // scope for the mutex Mutex::Autolock l(mLock); - size_t count = mGarbage.size(); - for (size_t i = 0; i < count; i++) { - const uint32_t generationID = mGarbage.itemAt(i); - + for (const uint32_t generationID : mGarbage) { LruCache<PathDescription, PathTexture*>::Iterator iter(mCache); while (iter.next()) { const PathDescription& key = iter.key(); diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index 70148631db34..31f8d3553375 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -28,7 +28,8 @@ #include <SkPath.h> #include <utils/LruCache.h> #include <utils/Mutex.h> -#include <utils/Vector.h> + +#include <vector> class SkBitmap; class SkCanvas; @@ -307,7 +308,7 @@ private: sp<PathProcessor> mProcessor; - Vector<uint32_t> mGarbage; + std::vector<uint32_t> mGarbage; mutable Mutex mLock; }; // class PathCache diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp index 38f214ab3e5d..8fa187c1e530 100644 --- a/libs/hwui/PathTessellator.cpp +++ b/libs/hwui/PathTessellator.cpp @@ -13,10 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#define LOG_TAG "OpenGLRenderer" #define LOG_NDEBUG 1 -#define ATRACE_TAG ATRACE_TAG_VIEW #define VERTEX_DEBUG 0 @@ -180,7 +177,8 @@ public: } }; -void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) { +void getFillVerticesFromPerimeter(const std::vector<Vertex>& perimeter, + VertexBuffer& vertexBuffer) { Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size()); int currentIndex = 0; @@ -204,8 +202,8 @@ void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& * Uses an additional 2 vertices at the end to wrap around, closing the tri-strip * (for a total of perimeter.size() * 2 + 2 vertices) */ -void getStrokeVerticesFromPerimeter(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter, - VertexBuffer& vertexBuffer) { +void getStrokeVerticesFromPerimeter(const PaintInfo& paintInfo, + const std::vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) { Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size() * 2 + 2); int currentIndex = 0; @@ -263,7 +261,7 @@ static inline void storeBeginEnd(const PaintInfo& paintInfo, const Vertex& cente * 2 - can zig-zag across 'extra' vertices at either end, to create round caps */ void getStrokeVerticesFromUnclosedVertices(const PaintInfo& paintInfo, - const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) { + const std::vector<Vertex>& vertices, VertexBuffer& vertexBuffer) { const int extra = paintInfo.capExtraDivisions(); const int allocSize = (vertices.size() + extra) * 2; Vertex* buffer = vertexBuffer.alloc<Vertex>(allocSize); @@ -342,8 +340,9 @@ void getStrokeVerticesFromUnclosedVertices(const PaintInfo& paintInfo, * * 3 - zig zag back and forth inside the shape to fill it (using perimeter.size() vertices) */ -void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter, - VertexBuffer& vertexBuffer, float maxAlpha = 1.0f) { +void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, + const std::vector<Vertex>& perimeter, VertexBuffer& vertexBuffer, + float maxAlpha = 1.0f) { AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2); // generate alpha points - fill Alpha vertex gaps in between each point with @@ -401,7 +400,7 @@ void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Ver * For explanation of constants and general methodoloyg, see comments for * getStrokeVerticesFromUnclosedVerticesAA() below. */ -inline static void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices, +inline static void storeCapAA(const PaintInfo& paintInfo, const std::vector<Vertex>& vertices, AlphaVertex* buffer, bool isFirst, Vector2 normal, int offset) { const int extra = paintInfo.capExtraDivisions(); const int extraOffset = (extra + 1) / 2; @@ -426,8 +425,8 @@ inline static void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& } // determine referencePoint, the center point for the 4 primary cap vertices - const Vertex* point = isFirst ? vertices.begin() : (vertices.end() - 1); - Vector2 referencePoint = {point->x, point->y}; + const Vertex& point = isFirst ? vertices.front() : vertices.back(); + Vector2 referencePoint = {point.x, point.y}; if (paintInfo.cap == SkPaint::kSquare_Cap) { // To account for square cap, move the primary cap vertices (that create the AA edge) by the // stroke offset vector (rotated to be parallel to the stroke) @@ -572,7 +571,7 @@ or, for rounded caps: = 2 + 6 * pts + 6 * roundDivs */ void getStrokeVerticesFromUnclosedVerticesAA(const PaintInfo& paintInfo, - const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) { + const std::vector<Vertex>& vertices, VertexBuffer& vertexBuffer) { const int extra = paintInfo.capExtraDivisions(); const int allocSize = 6 * vertices.size() + 2 + 6 * extra; @@ -645,8 +644,8 @@ void getStrokeVerticesFromUnclosedVerticesAA(const PaintInfo& paintInfo, } -void getStrokeVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter, - VertexBuffer& vertexBuffer) { +void getStrokeVerticesFromPerimeterAA(const PaintInfo& paintInfo, + const std::vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) { AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * perimeter.size() + 8); int offset = 2 * perimeter.size() + 3; @@ -724,7 +723,7 @@ void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint, const PaintInfo paintInfo(paint, transform); - Vector<Vertex> tempVertices; + std::vector<Vertex> tempVertices; float threshInvScaleX = paintInfo.inverseScaleX; float threshInvScaleY = paintInfo.inverseScaleY; if (paintInfo.style == SkPaint::kStroke_Style) { @@ -819,7 +818,7 @@ void PathTessellator::tessellatePoints(const float* points, int count, const SkP } // calculate outline - Vector<Vertex> outlineVertices; + std::vector<Vertex> outlineVertices; PathApproximationInfo approximationInfo(paintInfo.inverseScaleX, paintInfo.inverseScaleY, OUTLINE_REFINE_THRESHOLD); approximatePathOutlineVertices(path, true, approximationInfo, outlineVertices); @@ -861,10 +860,8 @@ void PathTessellator::tessellateLines(const float* points, int count, const SkPa vertexBuffer.alloc<Vertex>(numLines * lineAllocSize + (numLines - 1) * 2); } - Vector<Vertex> tempVertices; - tempVertices.push(); - tempVertices.push(); - Vertex* tempVerticesData = tempVertices.editArray(); + std::vector<Vertex> tempVertices(2); + Vertex* tempVerticesData = &tempVertices.front(); Rect bounds; bounds.set(points[0], points[1], points[0], points[1]); for (int i = 0; i < count; i += 4) { @@ -900,18 +897,11 @@ void PathTessellator::tessellateLines(const float* points, int count, const SkPa /////////////////////////////////////////////////////////////////////////////// bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, float threshold, - Vector<Vertex>& outputVertices) { + std::vector<Vertex>& outputVertices) { PathApproximationInfo approximationInfo(1.0f, 1.0f, threshold); return approximatePathOutlineVertices(path, true, approximationInfo, outputVertices); } -void pushToVector(Vector<Vertex>& vertices, float x, float y) { - // TODO: make this not yuck - vertices.push(); - Vertex* newVertex = &(vertices.editArray()[vertices.size() - 1]); - Vertex::set(newVertex, x, y); -} - class ClockwiseEnforcer { public: void addPoint(const SkPoint& point) { @@ -927,15 +917,15 @@ public: lastX = x; lastY = y; } - void reverseVectorIfNotClockwise(Vector<Vertex>& vertices) { + void reverseVectorIfNotClockwise(std::vector<Vertex>& vertices) { if (sum < 0) { // negative sum implies CounterClockwise const int size = vertices.size(); for (int i = 0; i < size / 2; i++) { Vertex tmp = vertices[i]; int k = size - 1 - i; - vertices.replaceAt(vertices[k], i); - vertices.replaceAt(tmp, k); + vertices[i] = vertices[k]; + vertices[k] = tmp; } } } @@ -947,7 +937,7 @@ private: }; bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool forceClose, - const PathApproximationInfo& approximationInfo, Vector<Vertex>& outputVertices) { + const PathApproximationInfo& approximationInfo, std::vector<Vertex>& outputVertices) { ATRACE_CALL(); // TODO: to support joins other than sharp miter, join vertices should be labelled in the @@ -959,7 +949,7 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo while (SkPath::kDone_Verb != (v = iter.next(pts))) { switch (v) { case SkPath::kMove_Verb: - pushToVector(outputVertices, pts[0].x(), pts[0].y()); + outputVertices.push_back(Vertex{pts[0].x(), pts[0].y()}); ALOGV("Move to pos %f %f", pts[0].x(), pts[0].y()); clockwiseEnforcer.addPoint(pts[0]); break; @@ -969,7 +959,7 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo break; case SkPath::kLine_Verb: ALOGV("kLine_Verb %f %f -> %f %f", pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y()); - pushToVector(outputVertices, pts[1].x(), pts[1].y()); + outputVertices.push_back(Vertex{pts[1].x(), pts[1].y()}); clockwiseEnforcer.addPoint(pts[1]); break; case SkPath::kQuad_Verb: @@ -1020,7 +1010,7 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo int size = outputVertices.size(); if (size >= 2 && outputVertices[0].x == outputVertices[size - 1].x && outputVertices[0].y == outputVertices[size - 1].y) { - outputVertices.pop(); + outputVertices.pop_back(); wasClosed = true; } @@ -1048,7 +1038,7 @@ void PathTessellator::recursiveCubicBezierVertices( float p1x, float p1y, float c1x, float c1y, float p2x, float p2y, float c2x, float c2y, const PathApproximationInfo& approximationInfo, - Vector<Vertex>& outputVertices, int depth) { + std::vector<Vertex>& outputVertices, int depth) { float dx = p2x - p1x; float dy = p2y - p1y; float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx); @@ -1058,7 +1048,7 @@ void PathTessellator::recursiveCubicBezierVertices( if (depth >= MAX_DEPTH || d * d <= getThreshold(approximationInfo, dx, dy)) { // below thresh, draw line by adding endpoint - pushToVector(outputVertices, p2x, p2y); + outputVertices.push_back(Vertex{p2x, p2y}); } else { float p1c1x = (p1x + c1x) * 0.5f; float p1c1y = (p1y + c1y) * 0.5f; @@ -1093,7 +1083,7 @@ void PathTessellator::recursiveQuadraticBezierVertices( float bx, float by, float cx, float cy, const PathApproximationInfo& approximationInfo, - Vector<Vertex>& outputVertices, int depth) { + std::vector<Vertex>& outputVertices, int depth) { float dx = bx - ax; float dy = by - ay; // d is the cross product of vector (B-A) and (C-B). @@ -1102,7 +1092,7 @@ void PathTessellator::recursiveQuadraticBezierVertices( if (depth >= MAX_DEPTH || d * d <= getThreshold(approximationInfo, dx, dy)) { // below thresh, draw line by adding endpoint - pushToVector(outputVertices, bx, by); + outputVertices.push_back(Vertex{bx, by}); } else { float acx = (ax + cx) * 0.5f; float bcx = (bx + cx) * 0.5f; diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h index 16c8b36a6a9d..b66e83252fb3 100644 --- a/libs/hwui/PathTessellator.h +++ b/libs/hwui/PathTessellator.h @@ -17,13 +17,13 @@ #ifndef ANDROID_HWUI_PATH_TESSELLATOR_H #define ANDROID_HWUI_PATH_TESSELLATOR_H -#include <utils/Vector.h> - #include "Matrix.h" #include "Rect.h" #include "Vertex.h" #include "VertexBuffer.h" +#include <vector> + namespace android { namespace uirenderer { @@ -109,11 +109,11 @@ public: * @param outputVertices An empty Vector which will be populated with the output */ static bool approximatePathOutlineVertices(const SkPath &path, float threshold, - Vector<Vertex> &outputVertices); + std::vector<Vertex> &outputVertices); private: static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose, - const PathApproximationInfo& approximationInfo, Vector<Vertex> &outputVertices); + const PathApproximationInfo& approximationInfo, std::vector<Vertex> &outputVertices); /* endpoints a & b, @@ -124,7 +124,7 @@ private: float bx, float by, float cx, float cy, const PathApproximationInfo& approximationInfo, - Vector<Vertex> &outputVertices, int depth = 0); + std::vector<Vertex> &outputVertices, int depth = 0); /* endpoints p1, p2 @@ -136,7 +136,7 @@ private: float p2x, float p2y, float c2x, float c2y, const PathApproximationInfo& approximationInfo, - Vector<Vertex> &outputVertices, int depth = 0); + std::vector<Vertex> &outputVertices, int depth = 0); }; }; // namespace uirenderer diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp index 9665a68b0e77..96247260f0f4 100644 --- a/libs/hwui/PixelBuffer.cpp +++ b/libs/hwui/PixelBuffer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "PixelBuffer.h" #include "Debug.h" diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index 32713e9b36f3..e43b80d440e7 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <utils/Trace.h> #include "Program.h" diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 41adda15f367..7f16deb41813 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/String8.h> #include "Caches.h" diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 26d8bf754ddb..1a70d7c20f03 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -36,9 +36,6 @@ namespace uirenderer { // If turned on, text is interpreted as glyphs instead of UTF-16 #define RENDER_TEXT_AS_GLYPHS 1 -// Indicates whether to remove the biggest layers first, or the smaller ones -#define LAYER_REMOVE_BIGGEST_FIRST 0 - // Textures used by layers must have dimensions multiples of this number #define LAYER_SIZE 64 @@ -151,11 +148,8 @@ enum DebugLevel { #define PROPERTY_SKIP_EMPTY_DAMAGE "debug.hwui.skip_empty_damage" /** - * Setting this property will enable usage of EGL_KHR_swap_buffers_with_damage + * Setting this property will enable or disable usage of EGL_KHR_swap_buffers_with_damage * See: https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_swap_buffers_with_damage.txt - * Default is "false" temporarily - * TODO: Change to "true", make sure to remove the log in EglManager::swapBuffers - * before changing this to default to true! */ #define PROPERTY_SWAP_WITH_DAMAGE "debug.hwui.swap_with_damage" diff --git a/libs/hwui/RenderBufferCache.cpp b/libs/hwui/RenderBufferCache.cpp index d0812c96afd7..8beed2540e1c 100644 --- a/libs/hwui/RenderBufferCache.cpp +++ b/libs/hwui/RenderBufferCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/Log.h> #include "Debug.h" @@ -100,9 +98,8 @@ void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) { } void RenderBufferCache::clear() { - size_t count = mCache.size(); - for (size_t i = 0; i < count; i++) { - deleteBuffer(mCache.itemAt(i).mBuffer); + for (auto entry : mCache) { + deleteBuffer(entry.mBuffer); } mCache.clear(); } @@ -111,11 +108,11 @@ RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const RenderBuffer* buffer = nullptr; RenderBufferEntry entry(format, width, height); - ssize_t index = mCache.indexOf(entry); + auto iter = mCache.find(entry); - if (index >= 0) { - entry = mCache.itemAt(index); - mCache.removeAt(index); + if (iter != mCache.end()) { + entry = *iter; + mCache.erase(iter); buffer = entry.mBuffer; mSize -= buffer->getSize(); @@ -141,16 +138,14 @@ bool RenderBufferCache::put(RenderBuffer* buffer) { const uint32_t size = buffer->getSize(); if (size < mMaxSize) { while (mSize + size > mMaxSize) { - size_t position = 0; - - RenderBuffer* victim = mCache.itemAt(position).mBuffer; + RenderBuffer* victim = mCache.begin()->mBuffer; deleteBuffer(victim); - mCache.removeAt(position); + mCache.erase(mCache.begin()); } RenderBufferEntry entry(buffer); - mCache.add(entry); + mCache.insert(entry); mSize += size; RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)", diff --git a/libs/hwui/RenderBufferCache.h b/libs/hwui/RenderBufferCache.h index 6c668b09c40d..7f59ec1c48b1 100644 --- a/libs/hwui/RenderBufferCache.h +++ b/libs/hwui/RenderBufferCache.h @@ -20,7 +20,8 @@ #include <GLES2/gl2.h> #include "RenderBuffer.h" -#include "utils/SortedList.h" + +#include <set> namespace android { namespace uirenderer { @@ -100,14 +101,8 @@ private: return compare(*this, other) != 0; } - friend inline int strictly_order_type(const RenderBufferEntry& lhs, - const RenderBufferEntry& rhs) { - return RenderBufferEntry::compare(lhs, rhs) < 0; - } - - friend inline int compare_type(const RenderBufferEntry& lhs, - const RenderBufferEntry& rhs) { - return RenderBufferEntry::compare(lhs, rhs); + bool operator<(const RenderBufferEntry& other) const { + return RenderBufferEntry::compare(*this, other) < 0; } RenderBuffer* mBuffer; @@ -118,7 +113,7 @@ private: void deleteBuffer(RenderBuffer* buffer); - SortedList<RenderBufferEntry> mCache; + std::multiset<RenderBufferEntry> mCache; uint32_t mSize; uint32_t mMaxSize; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 0951fc158ace..af8aaa20342e 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define ATRACE_TAG ATRACE_TAG_VIEW -#define LOG_TAG "OpenGLRenderer" - #include "RenderNode.h" #include <algorithm> @@ -531,7 +528,7 @@ void RenderNode::computeOrdering() { void RenderNode::computeOrderingImpl( DrawRenderNodeOp* opState, const SkPath* outlineOfProjectionSurface, - Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, + std::vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, const mat4* transformFromProjectionSurface) { mProjectedNodes.clear(); if (mDisplayListData == nullptr || mDisplayListData->isEmpty()) return; @@ -545,7 +542,7 @@ void RenderNode::computeOrderingImpl( // composited projectee, flag for out of order draw, save matrix, and store in proj surface opState->mSkipInOrderDraw = true; opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface); - compositedChildrenOfProjectionSurface->add(opState); + compositedChildrenOfProjectionSurface->push_back(opState); } else { // standard in order draw opState->mSkipInOrderDraw = false; @@ -559,7 +556,7 @@ void RenderNode::computeOrderingImpl( RenderNode* child = childOp->mRenderNode; const SkPath* projectionOutline = nullptr; - Vector<DrawRenderNodeOp*>* projectionChildren = nullptr; + std::vector<DrawRenderNodeOp*>* projectionChildren = nullptr; const mat4* projectionTransform = nullptr; if (isProjectionReceiver && !child->properties().getProjectBackwards()) { // if receiving projections, collect projecting descendant @@ -641,7 +638,7 @@ void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) { } void RenderNode::buildZSortedChildList(const DisplayListData::Chunk& chunk, - Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) { + std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) { if (chunk.beginChildIndex == chunk.endChildIndex) return; for (unsigned int i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) { @@ -650,7 +647,7 @@ void RenderNode::buildZSortedChildList(const DisplayListData::Chunk& chunk, float childZ = child->properties().getZ(); if (!MathUtils::isZero(childZ) && chunk.reorderChildren) { - zTranslatedNodes.add(ZDrawRenderNodeOpPair(childZ, childOp)); + zTranslatedNodes.push_back(ZDrawRenderNodeOpPair(childZ, childOp)); childOp->mSkipInOrderDraw = true; } else if (!child->properties().getProjectBackwards()) { // regular, in order drawing DisplayList @@ -693,7 +690,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& if (revealClipPath) { frameAllocatedPath = handler.allocPathForFrame(); - Op(*outlinePath, *revealClipPath, kIntersect_PathOp, frameAllocatedPath); + Op(*outlinePath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath); outlinePath = frameAllocatedPath; } @@ -709,7 +706,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& clipBoundsPath.addRect(clipBounds.left, clipBounds.top, clipBounds.right, clipBounds.bottom); - Op(*outlinePath, clipBoundsPath, kIntersect_PathOp, frameAllocatedPath); + Op(*outlinePath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath); outlinePath = frameAllocatedPath; } @@ -722,7 +719,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& template <class T> void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode, - const Matrix4& initialTransform, const Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, + const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, OpenGLRenderer& renderer, T& handler) { const int size = zTranslatedNodes.size(); if (size == 0 @@ -899,7 +896,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { for (size_t chunkIndex = 0; chunkIndex < mDisplayListData->getChunks().size(); chunkIndex++) { const DisplayListData::Chunk& chunk = mDisplayListData->getChunks()[chunkIndex]; - Vector<ZDrawRenderNodeOpPair> zTranslatedNodes; + std::vector<ZDrawRenderNodeOpPair> zTranslatedNodes; buildZSortedChildList(chunk, zTranslatedNodes); issueOperationsOf3dChildren(kNegativeZChildren, @@ -913,7 +910,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { #endif handler(op, saveCountOffset, properties().getClipToBounds()); - if (CC_UNLIKELY(!mProjectedNodes.isEmpty() && projectionReceiveIndex >= 0 && + if (CC_UNLIKELY(!mProjectedNodes.empty() && projectionReceiveIndex >= 0 && opIndex == static_cast<size_t>(projectionReceiveIndex))) { issueOperationsOfProjectedChildren(renderer, handler); } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 025a4a416e4c..db72287c69c1 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -16,17 +16,12 @@ #ifndef RENDERNODE_H #define RENDERNODE_H -#ifndef LOG_TAG - #define LOG_TAG "OpenGLRenderer" -#endif - #include <SkCamera.h> #include <SkMatrix.h> #include <utils/LinearAllocator.h> #include <utils/RefBase.h> #include <utils/String8.h> -#include <utils/Vector.h> #include <cutils/compiler.h> @@ -38,6 +33,8 @@ #include "DisplayList.h" #include "RenderProperties.h" +#include <vector> + class SkBitmap; class SkPaint; class SkPath; @@ -180,7 +177,7 @@ public: private: typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair; - static size_t findNonNegativeIndex(const Vector<ZDrawRenderNodeOpPair>& nodes) { + static size_t findNonNegativeIndex(const std::vector<ZDrawRenderNodeOpPair>& nodes) { for (size_t i = 0; i < nodes.size(); i++) { if (nodes[i].key >= 0.0f) return i; } @@ -194,21 +191,21 @@ private: void computeOrderingImpl(DrawRenderNodeOp* opState, const SkPath* outlineOfProjectionSurface, - Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, + std::vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, const mat4* transformFromProjectionSurface); template <class T> inline void setViewProperties(OpenGLRenderer& renderer, T& handler); void buildZSortedChildList(const DisplayListData::Chunk& chunk, - Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes); + std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes); template<class T> inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler); template <class T> inline void issueOperationsOf3dChildren(ChildrenSelectMode mode, - const Matrix4& initialTransform, const Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, + const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, OpenGLRenderer& renderer, T& handler); template <class T> @@ -271,7 +268,7 @@ private: */ // for projection surfaces, contains a list of all children items - Vector<DrawRenderNodeOp*> mProjectedNodes; + std::vector<DrawRenderNodeOp*> mProjectedNodes; // How many references our parent(s) have to us. Typically this should alternate // between 2 and 1 (when a staging push happens we inc first then dec) diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 4f6ef4ef9e3d..a9ae9b5322be 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "RenderProperties.h" #include <utils/Trace.h> diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 75d81346d62a..b26e433cfa4c 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "ResourceCache.h" #include "Caches.h" diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp index 09d125839a68..220936551a60 100644 --- a/libs/hwui/ShadowTessellator.cpp +++ b/libs/hwui/ShadowTessellator.cpp @@ -14,13 +14,9 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <math.h> #include <utils/Log.h> #include <utils/Trace.h> -#include <utils/Vector.h> #include <utils/MathUtils.h> #include "AmbientShadow.h" diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 644a4f305a2e..b2d1fecdaa4c 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -26,6 +26,8 @@ #include <SkTArray.h> #include <SkTemplates.h> +#include <memory> + namespace android { // Holds an SkCanvas reference plus additional native data. @@ -55,6 +57,11 @@ public: virtual int width() override; virtual int height() override; + virtual void setHighContrastText(bool highContrastText) override { + mHighContrastText = highContrastText; + } + virtual bool isHighContrastText() override { return mHighContrastText; } + virtual int getSaveCount() const override; virtual int save(SkCanvas::SaveFlags flags) override; virtual void restore() override; @@ -95,6 +102,7 @@ public: virtual void drawLines(const float* points, int count, const SkPaint& paint) override; virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override; + virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override; virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) override; virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override; @@ -134,6 +142,8 @@ private: SkCanvas::SaveFlags saveFlags; }; + bool mHighContrastText = false; + void recordPartialSave(SkCanvas::SaveFlags flags); void saveClipsForFrame(SkTArray<SkClipStack::Element>& clips, int frameSaveCount); void applyClips(const SkTArray<SkClipStack::Element>& clips); @@ -143,7 +153,7 @@ private: void drawTextDecorations(float x, float y, float length, const SkPaint& paint); SkAutoTUnref<SkCanvas> mCanvas; - SkAutoTDelete<SkDeque> mSaveStack; // lazily allocated, tracks partial saves. + std::unique_ptr<SkDeque> mSaveStack; // lazily allocated, tracks partial saves. }; Canvas* Canvas::create_canvas(const SkBitmap& bitmap) { @@ -507,6 +517,14 @@ void SkiaCanvas::drawRect(float left, float top, float right, float bottom, } +void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { + SkRegion::Iterator it(region); + while (!it.done()) { + mCanvas->drawRect(SkRect::Make(it.rect()), paint); + it.next(); + } +} + void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) { SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp index d96ca2afed00..0e5132582b07 100644 --- a/libs/hwui/SkiaCanvasProxy.cpp +++ b/libs/hwui/SkiaCanvasProxy.cpp @@ -18,6 +18,11 @@ #include <cutils/log.h> #include <SkPatchUtils.h> +#include <SkPaint.h> +#include <SkPath.h> +#include <SkPixelRef.h> +#include <SkRect.h> +#include <SkRRect.h> namespace android { namespace uirenderer { @@ -96,12 +101,31 @@ void SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) { void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, const SkPaint* paint) { - mCanvas->drawBitmap(bitmap, left, top, paint); + SkPixelRef* pxRef = bitmap.pixelRef(); + + // HWUI doesn't support extractSubset(), so convert any subsetted bitmap into + // a drawBitmapRect(); pass through an un-subsetted bitmap. + if (pxRef && bitmap.dimensions() != pxRef->info().dimensions()) { + SkBitmap fullBitmap; + fullBitmap.setInfo(pxRef->info()); + fullBitmap.setPixelRef(pxRef, 0, 0); + SkIPoint origin = bitmap.pixelRefOrigin(); + mCanvas->drawBitmap(fullBitmap, origin.fX, origin.fY, + origin.fX + bitmap.dimensions().width(), + origin.fY + bitmap.dimensions().height(), + left, top, + left + bitmap.dimensions().width(), + top + bitmap.dimensions().height(), + paint); + } else { + mCanvas->drawBitmap(bitmap, left, top, paint); + } } void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr, const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags) { SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height()); + // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src? mCanvas->drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); } @@ -114,6 +138,7 @@ void SkiaCanvasProxy::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& ce void SkiaCanvasProxy::onDrawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint) { + // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src? mCanvas->save(SkCanvas::kMatrixClip_SaveFlag); mCanvas->setLocalMatrix(SkMatrix::I()); mCanvas->drawBitmap(bitmap, left, top, paint); diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 81d8516168dd..1f959469fb56 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "SkiaShader.h" #include "Caches.h" diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index beb2e1d0481c..fd077d9c8388 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include "Snapshot.h" #include <SkCanvas.h> diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index b8c98041a6bf..eaf03036b568 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - // The highest z value can't be higher than (CASTER_Z_CAP_RATIO * light.z) #define CASTER_Z_CAP_RATIO 0.95f diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp index 17cb3a7fd6fd..01f5e2dba214 100644 --- a/libs/hwui/TessellationCache.cpp +++ b/libs/hwui/TessellationCache.cpp @@ -225,13 +225,13 @@ static void tessellateShadows( VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer) { // tessellate caster outline into a 2d polygon - Vector<Vertex> casterVertices2d; + std::vector<Vertex> casterVertices2d; const float casterRefinementThreshold = 2.0f; PathTessellator::approximatePathOutlineVertices(*casterPerimeter, casterRefinementThreshold, casterVertices2d); // Shadow requires CCW for now. TODO: remove potential double-reverse - reverseVertexArray(casterVertices2d.editArray(), casterVertices2d.size()); + reverseVertexArray(&casterVertices2d.front(), casterVertices2d.size()); if (casterVertices2d.size() == 0) return; @@ -250,7 +250,7 @@ static void tessellateShadows( // map the centroid of the caster into 3d Vector2 centroid = ShadowTessellator::centroid2d( - reinterpret_cast<const Vector2*>(casterVertices2d.array()), + reinterpret_cast<const Vector2*>(&casterVertices2d.front()), casterVertexCount); Vector3 centroid3d = {centroid.x, centroid.y, 0}; mapPointFakeZ(centroid3d, casterTransformXY, casterTransformZ); diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h index 3efeaf64d486..b54666b7d595 100644 --- a/libs/hwui/TessellationCache.h +++ b/libs/hwui/TessellationCache.h @@ -19,7 +19,6 @@ #include <utils/LruCache.h> #include <utils/Mutex.h> -#include <utils/Vector.h> #include "Debug.h" #include "utils/Macros.h" diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index 8b1d4cb2196c..b7a76baadff5 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/JenkinsHash.h> #include "Caches.h" diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp index 593e91818093..5195b457af2b 100644 --- a/libs/hwui/Texture.cpp +++ b/libs/hwui/Texture.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <utils/Log.h> #include "Caches.h" diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index fda009108aba..16f6f4ba4bb6 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <GLES2/gl2.h> #include <SkCanvas.h> @@ -219,14 +216,14 @@ Texture* TextureCache::get(const SkBitmap* bitmap, AtlasUsageType atlasUsageType void TextureCache::releaseTexture(uint32_t pixelRefStableID) { Mutex::Autolock _l(mLock); - mGarbage.push(pixelRefStableID); + mGarbage.push_back(pixelRefStableID); } void TextureCache::clearGarbage() { Mutex::Autolock _l(mLock); size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { - uint32_t pixelRefId = mGarbage.itemAt(i); + uint32_t pixelRefId = mGarbage[i]; mCache.remove(pixelRefId); } mGarbage.clear(); diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 7a7ee5aeb554..ebd1885e75e1 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -21,10 +21,11 @@ #include <utils/LruCache.h> #include <utils/Mutex.h> -#include <utils/Vector.h> #include "Debug.h" +#include <vector> + namespace android { namespace uirenderer { @@ -165,7 +166,7 @@ private: bool mDebugEnabled; - Vector<uint32_t> mGarbage; + std::vector<uint32_t> mGarbage; mutable Mutex mLock; AssetAtlas* mAssetAtlas; diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h index 11d0c4bef84f..c1bf980658b2 100644 --- a/libs/hwui/Vertex.h +++ b/libs/hwui/Vertex.h @@ -37,7 +37,6 @@ struct Vertex { */ static float GeometryFudgeFactor() { return 0.0656f; } - float x, y; static inline void set(Vertex* vertex, float x, float y) { diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index 5de64a4b1654..fb0753bbc76c 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -14,15 +14,12 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include <cutils/compiler.h> #include <utils/JenkinsHash.h> #include <utils/Trace.h> -#include <SkDeviceProperties.h> +#include <SkSurfaceProps.h> #include <SkGlyph.h> #include <SkGlyphCache.h> #include <SkUtils.h> @@ -284,8 +281,8 @@ CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bo if (cachedGlyph) { // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { - SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); - SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); + SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry); + SkAutoGlyphCacheNoGamma autoCache(*paint, &surfaceProps, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit); updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching); } @@ -475,8 +472,8 @@ CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool prec CachedGlyphInfo* newGlyph = new CachedGlyphInfo(); mCachedGlyphs.add(glyph, newGlyph); - SkDeviceProperties deviceProperties(kUnknown_SkPixelGeometry, 1.0f); - SkAutoGlyphCache autoCache(*paint, &deviceProperties, &mDescription.mLookupTransform); + SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry); + SkAutoGlyphCacheNoGamma autoCache(*paint, &surfaceProps, &mDescription.mLookupTransform); const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph); newGlyph->mIsValid = false; newGlyph->mGlyphIndex = skiaGlyph.fID; diff --git a/libs/hwui/renderstate/Stencil.h b/libs/hwui/renderstate/Stencil.h index 3a8f8ebad48d..32618230bbf6 100644 --- a/libs/hwui/renderstate/Stencil.h +++ b/libs/hwui/renderstate/Stencil.h @@ -17,10 +17,6 @@ #ifndef ANDROID_HWUI_STENCIL_H #define ANDROID_HWUI_STENCIL_H -#ifndef LOG_TAG - #define LOG_TAG "OpenGLRenderer" -#endif - #include <GLES2/gl2.h> #include <cutils/compiler.h> diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 6dfb6e811e60..ea7338732664 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -98,6 +98,9 @@ void CanvasContext::swapBuffers(const SkRect& dirty, EGLint width, EGLint height setSurface(nullptr); } mHaveNewSurface = false; + if (mEglManager.useBufferAgeExt()) { + mDirtyHistory.prepend(Rect(dirty)); + } } void CanvasContext::requireSurface() { @@ -227,6 +230,8 @@ void CanvasContext::draw() { "drawRenderNode called on a context with no canvas or surface!"); SkRect dirty; + bool useBufferAgeExt = mEglManager.useBufferAgeExt(); + Rect patchedDirty; mDamageAccumulator.finish(&dirty); // TODO: Re-enable after figuring out cause of b/22592975 @@ -237,12 +242,18 @@ void CanvasContext::draw() { mCurrentFrameInfo->markIssueDrawCommandsStart(); - EGLint width, height; - mEglManager.beginFrame(mEglSurface, &width, &height); + EGLint width, height, framebufferAge; + mEglManager.beginFrame(mEglSurface, &width, &height, &framebufferAge); + + if (useBufferAgeExt && mHaveNewSurface) { + mDirtyHistory.clear(); + } + if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { mCanvas->setViewport(width, height); dirty.setEmpty(); } else if (!mBufferPreserved || mHaveNewSurface) { + mDirtyHistory.clear(); dirty.setEmpty(); } else { if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) { @@ -253,9 +264,14 @@ void CanvasContext::draw() { profiler().unionDirty(&dirty); } - if (!dirty.isEmpty()) { - mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, - dirty.fRight, dirty.fBottom, mOpaque); + patchedDirty = dirty; + if (useBufferAgeExt && !dirty.isEmpty()) { + patchedDirty = mDirtyHistory.unionWith(Rect(dirty), framebufferAge-1); + } + + if (!patchedDirty.isEmpty()) { + mCanvas->prepareDirty(patchedDirty.left, patchedDirty.top, + patchedDirty.right, patchedDirty.bottom, mOpaque); } else { mCanvas->prepare(mOpaque); } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index f2fa9cdcbefd..59f9c3a288dc 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -25,13 +25,13 @@ #include "utils/RingBuffer.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" +#include "renderthread/DirtyHistory.h" #include <cutils/compiler.h> #include <EGL/egl.h> #include <SkBitmap.h> #include <SkRect.h> #include <utils/Functor.h> -#include <utils/Vector.h> #include <set> #include <string> @@ -147,6 +147,8 @@ private: FrameInfoVisualizer mProfiler; std::set<RenderNode*> mPrefetechedLayers; + + DirtyHistory mDirtyHistory; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/DirtyHistory.cpp b/libs/hwui/renderthread/DirtyHistory.cpp new file mode 100644 index 000000000000..1419e84ec444 --- /dev/null +++ b/libs/hwui/renderthread/DirtyHistory.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 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. + */ +#include "DirtyHistory.h" + +namespace android { +namespace uirenderer { +namespace renderthread { + +DirtyHistory::DirtyHistory() + : mBack(DIRTY_HISTORY_SIZE - 1) { + clear(); +} + +void DirtyHistory::clear() +{ + for (int i = 0; i < DIRTY_HISTORY_SIZE; i++) { + mHistory[i].clear(); + } +} + +Rect DirtyHistory::get(int index) { + if (index >= DIRTY_HISTORY_SIZE || index < 0) + return Rect(); + return mHistory[(1 + mBack + index) % DIRTY_HISTORY_SIZE]; +} + +Rect DirtyHistory::unionWith(Rect rect, int count) { + if (rect.isEmpty() || count > DIRTY_HISTORY_SIZE || count < 0) + return Rect(); + + for (int i = 0; i < count; i++) { + Rect ith = get(i); + if (ith.isEmpty()) + return Rect(); + + // rect union + rect.left = fminf(rect.left, ith.left); + rect.top = fminf(rect.top, ith.top); + rect.right = fmaxf(rect.right, ith.right); + rect.bottom = fmaxf(rect.bottom, ith.bottom); + } + return rect; +} + +void DirtyHistory::prepend(Rect rect) { + if (rect.isEmpty()) { + mHistory[mBack].clear(); + } else { + mHistory[mBack].set(rect); + } + mBack = (mBack + DIRTY_HISTORY_SIZE - 1) % DIRTY_HISTORY_SIZE; +} + +} /* namespace renderthread */ +} /* namespace uirenderer */ +} /* namespace android */ diff --git a/libs/hwui/renderthread/DirtyHistory.h b/libs/hwui/renderthread/DirtyHistory.h new file mode 100644 index 000000000000..d5ea597878aa --- /dev/null +++ b/libs/hwui/renderthread/DirtyHistory.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 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 DIRTYHISTORY_H +#define DIRTYHISTORY_H + +#include <Rect.h> + +namespace android { +namespace uirenderer { +namespace renderthread { + +#define DIRTY_HISTORY_SIZE 4 + +class DirtyHistory { +public: + DirtyHistory(); + ~DirtyHistory() {} + + Rect get(int index); + Rect unionWith(Rect rect, int count); + void prepend(Rect rect); + void clear(); +private: + Rect mHistory[DIRTY_HISTORY_SIZE]; + int mBack; +}; + +} /* namespace renderthread */ +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* DIRTYHISTORY_H */ diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index a4ac13bb95a1..198906ca845e 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define ATRACE_TAG ATRACE_TAG_VIEW - #include "DrawFrameTask.h" #include <utils/Log.h> diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index eb332d59fee3..ac36f5363eec 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -76,6 +76,7 @@ EglManager::EglManager(RenderThread& thread) , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mAllowPreserveBuffer(load_dirty_regions_property()) + , mHasBufferAgeExt(false) , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(nullptr) , mAtlasMapSize(0) { @@ -98,7 +99,10 @@ void EglManager::initialize() { ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor); - loadConfig(); + findExtensions(eglQueryString(mEglDisplay, EGL_EXTENSIONS), mEglExtensionList); + mHasBufferAgeExt = hasEglExtension("EGL_EXT_buffer_age"); + + loadConfig(mHasBufferAgeExt); createContext(); createPBufferSurface(); makeCurrent(mPBufferSurface); @@ -110,8 +114,13 @@ bool EglManager::hasEglContext() { return mEglDisplay != EGL_NO_DISPLAY; } -void EglManager::loadConfig() { - EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; +bool EglManager::hasEglExtension(const char* extension) const { + const std::string s(extension); + return mEglExtensionList.find(s) != mEglExtensionList.end(); +} + +void EglManager::loadConfig(bool useBufferAgeExt) { + EGLint swapBehavior = (!useBufferAgeExt && mCanSetPreserveBuffer) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, @@ -133,7 +142,7 @@ void EglManager::loadConfig() { ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); // Try again without dirty regions enabled mCanSetPreserveBuffer = false; - loadConfig(); + loadConfig(useBufferAgeExt); } else { LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); } @@ -238,7 +247,7 @@ bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut) { return true; } -void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { +void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height, EGLint* framebufferAge) { LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, "Tried to beginFrame on EGL_NO_SURFACE!"); makeCurrent(surface); @@ -248,6 +257,9 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { if (height) { eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); } + if (useBufferAgeExt()) { + eglQuerySurface(mEglDisplay, surface, EGL_BUFFER_AGE_EXT, framebufferAge); + } eglBeginFrame(mEglDisplay, surface); } @@ -304,6 +316,10 @@ bool EglManager::swapBuffers(EGLSurface surface, const SkRect& dirty, return false; } +bool EglManager::useBufferAgeExt() { + return mAllowPreserveBuffer && mHasBufferAgeExt; +} + void EglManager::fence() { EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL); eglClientWaitSyncKHR(mEglDisplay, fence, @@ -314,6 +330,9 @@ void EglManager::fence() { bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false; + // Use EGL_EXT_buffer_age instead if supported + if (mHasBufferAgeExt) return true; + bool preserved = false; if (mCanSetPreserveBuffer) { preserved = eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, @@ -337,6 +356,19 @@ bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { return preserved; } +void EglManager::findExtensions(const char* extensions, std::set<std::string>& list) const { + const char* current = extensions; + const char* head = current; + do { + head = strchr(current, ' '); + std::string s(current, head ? head - current : strlen(current)); + if (s.length()) { + list.insert(s); + } + current = head + 1; + } while (head); +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index 0a8cfd30df71..bb5d24b0557f 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -21,6 +21,7 @@ #include <SkRect.h> #include <ui/GraphicBuffer.h> #include <utils/StrongPointer.h> +#include <set> namespace android { namespace uirenderer { @@ -37,6 +38,8 @@ public: bool hasEglContext(); + bool hasEglExtension(const char* extension) const; + EGLSurface createSurface(EGLNativeWindowType window); void destroySurface(EGLSurface surface); @@ -45,12 +48,14 @@ public: bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; } // Returns true if the current surface changed, false if it was already current bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr); - void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); + void beginFrame(EGLSurface surface, EGLint* width, EGLint* height, EGLint* framebufferAge); bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height); // Returns true iff the surface is now preserving buffers. bool setPreserveBuffer(EGLSurface surface, bool preserve); + bool useBufferAgeExt(); + void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); void fence(); @@ -63,10 +68,12 @@ private: ~EglManager(); void createPBufferSurface(); - void loadConfig(); + void loadConfig(bool useBufferAgeExt); void createContext(); void initAtlas(); + void findExtensions(const char* extensions, std::set<std::string>& list) const; + RenderThread& mRenderThread; EGLDisplay mEglDisplay; @@ -77,11 +84,15 @@ private: const bool mAllowPreserveBuffer; bool mCanSetPreserveBuffer; + bool mHasBufferAgeExt; + EGLSurface mCurrentSurface; sp<GraphicBuffer> mAtlasBuffer; int64_t* mAtlasMap; size_t mAtlasMapSize; + + std::set<std::string> mEglExtensionList; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 6d9acd429279..a3a0163f2e08 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -271,16 +271,15 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) { postAndWait(task); } -CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) { +CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) { Layer* layer = args->context->createTextureLayer(); if (!layer) return nullptr; - return new DeferredLayerUpdater(*args->thread, layer); + return new DeferredLayerUpdater(layer); } DeferredLayerUpdater* RenderProxy::createTextureLayer() { SETUP_TASK(createTextureLayer); args->context = mContext; - args->thread = &mRenderThread; void* retval = postAndWait(task); DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval); return layer; diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 5febbe0ab26c..0d2c7be5b317 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -27,7 +27,6 @@ #include <utils/Mutex.h> #include <utils/Timers.h> #include <utils/StrongPointer.h> -#include <utils/Vector.h> #include "../Caches.h" #include "../IContextFactory.h" diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/TestContext.cpp index 3687a5003471..cebe7650dea2 100644 --- a/libs/hwui/tests/TestContext.cpp +++ b/libs/hwui/tests/TestContext.cpp @@ -57,10 +57,7 @@ sp<Surface> TestContext::surface() { } void TestContext::waitForVsync() { -#if HWUI_NULL_GPU - return; -#endif - +#if !HWUI_NULL_GPU // Request vsync mDisplayEventReceiver.requestNextVsync(); @@ -70,6 +67,7 @@ void TestContext::waitForVsync() { // Drain it DisplayEventReceiver::Event buf[100]; while (mDisplayEventReceiver.getEvents(buf, 100) > 0) { } +#endif } } // namespace test diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index 80d7029857c4..69e822510c31 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -42,15 +42,12 @@ public: }; static DisplayListCanvas* startRecording(RenderNode* node) { - DisplayListCanvas* renderer = new DisplayListCanvas(); - renderer->setViewport(node->stagingProperties().getWidth(), - node->stagingProperties().getHeight()); - renderer->prepare(); + DisplayListCanvas* renderer = new DisplayListCanvas( + node->stagingProperties().getWidth(), node->stagingProperties().getHeight()); return renderer; } static void endRecording(DisplayListCanvas* renderer, RenderNode* node) { - renderer->finish(); node->setStagingDisplayList(renderer->finishRecording()); delete renderer; } @@ -233,21 +230,16 @@ private: DisplayListCanvas* renderer = startRecording(node.get()); renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode); - float rects[width * height]; - int index = 0; + SkRegion region; for (int xOffset = 0; xOffset < width; xOffset+=2) { for (int yOffset = 0; yOffset < height; yOffset+=2) { - rects[index++] = xOffset; - rects[index++] = yOffset; - rects[index++] = xOffset + 1; - rects[index++] = yOffset + 1; + region.op(xOffset, yOffset, xOffset + 1, yOffset + 1, SkRegion::kUnion_Op); } } - int count = width * height; SkPaint paint; paint.setColor(0xff00ffff); - renderer->drawRects(rects, count, &paint); + renderer->drawRegion(region, paint); endRecording(renderer, node.get()); return node; diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp index e9dde294b2aa..a07845ecf659 100644 --- a/libs/hwui/thread/TaskManager.cpp +++ b/libs/hwui/thread/TaskManager.cpp @@ -39,7 +39,7 @@ TaskManager::TaskManager() { for (int i = 0; i < workerCount; i++) { String8 name; name.appendFormat("hwuiTask%d", i + 1); - mThreads.add(new WorkerThread(name)); + mThreads.push_back(new WorkerThread(name)); } } @@ -89,15 +89,14 @@ status_t TaskManager::WorkerThread::readyToRun() { bool TaskManager::WorkerThread::threadLoop() { mSignal.wait(); - Vector<TaskWrapper> tasks; + std::vector<TaskWrapper> tasks; { Mutex::Autolock l(mLock); - tasks = mTasks; - mTasks.clear(); + tasks.swap(mTasks); } for (size_t i = 0; i < tasks.size(); i++) { - const TaskWrapper& task = tasks.itemAt(i); + const TaskWrapper& task = tasks[i]; task.mProcessor->process(task.mTask); } @@ -111,14 +110,13 @@ bool TaskManager::WorkerThread::addTask(TaskWrapper task) { return false; } - ssize_t index; { Mutex::Autolock l(mLock); - index = mTasks.add(task); + mTasks.push_back(task); } mSignal.signal(); - return index >= 0; + return true; } size_t TaskManager::WorkerThread::getTaskCount() const { diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index 10e8b9e0bead..d0eb3049ae37 100644 --- a/libs/hwui/thread/TaskManager.h +++ b/libs/hwui/thread/TaskManager.h @@ -20,10 +20,11 @@ #include <utils/Mutex.h> #include <utils/String8.h> #include <utils/Thread.h> -#include <utils/Vector.h> #include "Signal.h" +#include <vector> + namespace android { namespace uirenderer { @@ -89,7 +90,7 @@ private: // Lock for the list of tasks mutable Mutex mLock; - Vector<TaskWrapper> mTasks; + std::vector<TaskWrapper> mTasks; // Signal used to wake up the thread when a new // task is available in the list @@ -98,7 +99,7 @@ private: const String8 mName; }; - Vector<sp<WorkerThread> > mThreads; + std::vector<sp<WorkerThread> > mThreads; }; }; // namespace uirenderer diff --git a/libs/hwui/utils/Blur.cpp b/libs/hwui/utils/Blur.cpp index 877a42216c27..6884aedc2bff 100644 --- a/libs/hwui/utils/Blur.cpp +++ b/libs/hwui/utils/Blur.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <math.h> #include "Blur.h" diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp index 59b12cf66a89..01cf5d2af4de 100644 --- a/libs/hwui/utils/LinearAllocator.cpp +++ b/libs/hwui/utils/LinearAllocator.cpp @@ -32,7 +32,7 @@ // The ideal size of a page allocation (these need to be multiples of 8) -#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb +#define INITIAL_PAGE_SIZE ((size_t)512) // 512b #define MAX_PAGE_SIZE ((size_t)131072) // 128kb // The maximum amount of wasted space we can have per page @@ -40,7 +40,7 @@ // If this is too low, we will malloc too much // Too high, and we may waste too much space // Must be smaller than INITIAL_PAGE_SIZE -#define MAX_WASTE_SIZE ((size_t)1024) +#define MAX_WASTE_RATIO (0.5f) #if ALIGN_DOUBLE #define ALIGN_SZ (sizeof(double)) @@ -114,7 +114,7 @@ private: LinearAllocator::LinearAllocator() : mPageSize(INITIAL_PAGE_SIZE) - , mMaxAllocSize(MAX_WASTE_SIZE) + , mMaxAllocSize(INITIAL_PAGE_SIZE * MAX_WASTE_RATIO) , mNext(0) , mCurrentPage(0) , mPages(0) @@ -156,6 +156,7 @@ void LinearAllocator::ensureNext(size_t size) { if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) { mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2); + mMaxAllocSize = mPageSize * MAX_WASTE_RATIO; mPageSize = ALIGN(mPageSize); } mWastedSpace += mPageSize; diff --git a/libs/hwui/utils/SortedList.h b/libs/hwui/utils/SortedList.h deleted file mode 100644 index a2c8c52fcbc7..000000000000 --- a/libs/hwui/utils/SortedList.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2010 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_SORTED_LIST_H -#define ANDROID_HWUI_SORTED_LIST_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Vector.h> -#include <utils/TypeHelpers.h> - -#include "SortedListImpl.h" - -namespace android { -namespace uirenderer { - -/////////////////////////////////////////////////////////////////////////////// -// Sorted list -/////////////////////////////////////////////////////////////////////////////// - -template<class TYPE> -class SortedList: private SortedListImpl { -public: - typedef TYPE value_type; - - SortedList(); - SortedList(const SortedList<TYPE>& rhs); - virtual ~SortedList(); - - const SortedList<TYPE>& operator =(const SortedList<TYPE>& rhs) const; - SortedList<TYPE>& operator =(const SortedList<TYPE>& rhs); - - inline void clear() { - VectorImpl::clear(); - } - - inline size_t size() const { - return VectorImpl::size(); - } - - inline bool isEmpty() const { - return VectorImpl::isEmpty(); - } - - inline size_t capacity() const { - return VectorImpl::capacity(); - } - - inline ssize_t setCapacity(size_t size) { - return VectorImpl::setCapacity(size); - } - - inline const TYPE* array() const; - - TYPE* editArray(); - - ssize_t indexOf(const TYPE& item) const; - size_t orderOf(const TYPE& item) const; - - inline const TYPE& operator [](size_t index) const; - inline const TYPE& itemAt(size_t index) const; - const TYPE& top() const; - const TYPE& mirrorItemAt(ssize_t index) const; - - ssize_t add(const TYPE& item); - - TYPE& editItemAt(size_t index) { - return *(static_cast<TYPE *> (VectorImpl::editItemLocation(index))); - } - - ssize_t merge(const Vector<TYPE>& vector); - ssize_t merge(const SortedList<TYPE>& vector); - - ssize_t remove(const TYPE&); - - inline ssize_t removeItemsAt(size_t index, size_t count = 1); - inline ssize_t removeAt(size_t index) { - return removeItemsAt(index); - } - -protected: - virtual void do_construct(void* storage, size_t num) const override; - virtual void do_destroy(void* storage, size_t num) const override; - virtual void do_copy(void* dest, const void* from, size_t num) const override; - virtual void do_splat(void* dest, const void* item, size_t num) const override; - virtual void do_move_forward(void* dest, const void* from, size_t num) const override; - virtual void do_move_backward(void* dest, const void* from, size_t num) const override; - virtual int do_compare(const void* lhs, const void* rhs) const override; -}; // class SortedList - -/////////////////////////////////////////////////////////////////////////////// -// Implementation -/////////////////////////////////////////////////////////////////////////////// - -template<class TYPE> -inline SortedList<TYPE>::SortedList(): - SortedListImpl(sizeof(TYPE), ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) - | (traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - | (traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))) { -} - -template<class TYPE> -inline SortedList<TYPE>::SortedList(const SortedList<TYPE>& rhs): SortedListImpl(rhs) { -} - -template<class TYPE> inline SortedList<TYPE>::~SortedList() { - finish_vector(); -} - -template<class TYPE> -inline SortedList<TYPE>& SortedList<TYPE>::operator =(const SortedList<TYPE>& rhs) { - SortedListImpl::operator =(rhs); - return *this; -} - -template<class TYPE> -inline const SortedList<TYPE>& SortedList<TYPE>::operator =( - const SortedList<TYPE>& rhs) const { - SortedListImpl::operator =(rhs); - return *this; -} - -template<class TYPE> -inline const TYPE* SortedList<TYPE>::array() const { - return static_cast<const TYPE *> (arrayImpl()); -} - -template<class TYPE> -inline TYPE* SortedList<TYPE>::editArray() { - return static_cast<TYPE *> (editArrayImpl()); -} - -template<class TYPE> -inline const TYPE& SortedList<TYPE>::operator[](size_t index) const { - assert( index<size() ); - return *(array() + index); -} - -template<class TYPE> -inline const TYPE& SortedList<TYPE>::itemAt(size_t index) const { - return operator[](index); -} - -template<class TYPE> -inline const TYPE& SortedList<TYPE>::mirrorItemAt(ssize_t index) const { - assert( (index>0 ? index : -index)<size() ); - return *(array() + ((index < 0) ? (size() - index) : index)); -} - -template<class TYPE> -inline const TYPE& SortedList<TYPE>::top() const { - return *(array() + size() - 1); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::add(const TYPE& item) { - return SortedListImpl::add(&item); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::indexOf(const TYPE& item) const { - return SortedListImpl::indexOf(&item); -} - -template<class TYPE> -inline size_t SortedList<TYPE>::orderOf(const TYPE& item) const { - return SortedListImpl::orderOf(&item); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::merge(const Vector<TYPE>& vector) { - return SortedListImpl::merge(reinterpret_cast<const VectorImpl&> (vector)); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::merge(const SortedList<TYPE>& vector) { - return SortedListImpl::merge(reinterpret_cast<const SortedListImpl&> (vector)); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::remove(const TYPE& item) { - return SortedListImpl::remove(&item); -} - -template<class TYPE> -inline ssize_t SortedList<TYPE>::removeItemsAt(size_t index, size_t count) { - return VectorImpl::removeItemsAt(index, count); -} - -template<class TYPE> -void SortedList<TYPE>::do_construct(void* storage, size_t num) const { - construct_type(reinterpret_cast<TYPE*> (storage), num); -} - -template<class TYPE> -void SortedList<TYPE>::do_destroy(void* storage, size_t num) const { - destroy_type(reinterpret_cast<TYPE*> (storage), num); -} - -template<class TYPE> -void SortedList<TYPE>::do_copy(void* dest, const void* from, size_t num) const { - copy_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num); -} - -template<class TYPE> -void SortedList<TYPE>::do_splat(void* dest, const void* item, size_t num) const { - splat_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (item), num); -} - -template<class TYPE> -void SortedList<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { - move_forward_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num); -} - -template<class TYPE> -void SortedList<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { - move_backward_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num); -} - -template<class TYPE> -int SortedList<TYPE>::do_compare(const void* lhs, const void* rhs) const { - return compare_type(*reinterpret_cast<const TYPE*> (lhs), *reinterpret_cast<const TYPE*> (rhs)); -} - -}; // namespace uirenderer -}; // namespace android - -#endif // ANDROID_HWUI_SORTED_LIST_H diff --git a/libs/hwui/utils/SortedListImpl.cpp b/libs/hwui/utils/SortedListImpl.cpp deleted file mode 100644 index 35171d5b1a5b..000000000000 --- a/libs/hwui/utils/SortedListImpl.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include "SortedListImpl.h" - -namespace android { -namespace uirenderer { - -/////////////////////////////////////////////////////////////////////////////// -// Sorted list implementation, not for direct use -/////////////////////////////////////////////////////////////////////////////// - -SortedListImpl::SortedListImpl(size_t itemSize, uint32_t flags): VectorImpl(itemSize, flags) { -} - -SortedListImpl::SortedListImpl(const VectorImpl& rhs): VectorImpl(rhs) { -} - -SortedListImpl::~SortedListImpl() { -} - -SortedListImpl& SortedListImpl::operator =(const SortedListImpl& rhs) { - return static_cast<SortedListImpl&> - (VectorImpl::operator =(static_cast<const VectorImpl&> (rhs))); -} - -ssize_t SortedListImpl::indexOf(const void* item) const { - return _indexOrderOf(item); -} - -size_t SortedListImpl::orderOf(const void* item) const { - size_t o; - _indexOrderOf(item, &o); - return o; -} - -ssize_t SortedListImpl::_indexOrderOf(const void* item, size_t* order) const { - // binary search - ssize_t err = NAME_NOT_FOUND; - ssize_t l = 0; - ssize_t h = size() - 1; - ssize_t mid; - const void* a = arrayImpl(); - const size_t s = itemSize(); - while (l <= h) { - mid = l + (h - l) / 2; - const void* const curr = reinterpret_cast<const char *> (a) + (mid * s); - const int c = do_compare(curr, item); - if (c == 0) { - err = l = mid; - break; - } else if (c < 0) { - l = mid + 1; - } else { - h = mid - 1; - } - } - if (order) { - *order = l; - } - return err; -} - -ssize_t SortedListImpl::add(const void* item) { - size_t order; - ssize_t index = _indexOrderOf(item, &order); - index = VectorImpl::insertAt(item, order, 1); - return index; -} - -ssize_t SortedListImpl::merge(const VectorImpl& vector) { - // naive merge... - if (!vector.isEmpty()) { - const void* buffer = vector.arrayImpl(); - const size_t is = itemSize(); - size_t s = vector.size(); - for (size_t i = 0; i < s; i++) { - ssize_t err = add(reinterpret_cast<const char*> (buffer) + i * is); - if (err < 0) { - return err; - } - } - } - return NO_ERROR; -} - -ssize_t SortedListImpl::merge(const SortedListImpl& vector) { - // we've merging a sorted vector... nice! - ssize_t err = NO_ERROR; - if (!vector.isEmpty()) { - // first take care of the case where the vectors are sorted together - if (do_compare(vector.itemLocation(vector.size() - 1), arrayImpl()) <= 0) { - err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&> (vector), 0); - } else if (do_compare(vector.arrayImpl(), itemLocation(size() - 1)) >= 0) { - err = VectorImpl::appendVector(static_cast<const VectorImpl&> (vector)); - } else { - // this could be made a little better - err = merge(static_cast<const VectorImpl&> (vector)); - } - } - return err; -} - -ssize_t SortedListImpl::remove(const void* item) { - ssize_t i = indexOf(item); - if (i >= 0) { - VectorImpl::removeItemsAt(i, 1); - } - return i; -} - -}; // namespace uirenderer -}; // namespace android diff --git a/libs/hwui/utils/SortedListImpl.h b/libs/hwui/utils/SortedListImpl.h deleted file mode 100644 index b1018265566a..000000000000 --- a/libs/hwui/utils/SortedListImpl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010 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_SORTED_LIST_IMPL_H -#define ANDROID_HWUI_SORTED_LIST_IMPL_H - -#include <utils/VectorImpl.h> - -namespace android { -namespace uirenderer { - -class SortedListImpl: public VectorImpl { -public: - SortedListImpl(size_t itemSize, uint32_t flags); - SortedListImpl(const VectorImpl& rhs); - virtual ~SortedListImpl(); - - SortedListImpl& operator =(const SortedListImpl& rhs); - - ssize_t indexOf(const void* item) const; - size_t orderOf(const void* item) const; - ssize_t add(const void* item); - ssize_t merge(const VectorImpl& vector); - ssize_t merge(const SortedListImpl& vector); - ssize_t remove(const void* item); - -protected: - virtual int do_compare(const void* lhs, const void* rhs) const = 0; - -private: - ssize_t _indexOrderOf(const void* item, size_t* order = nullptr) const; - - // these are made private, because they can't be used on a SortedVector - // (they don't have an implementation either) - ssize_t add(); - void pop(); - void push(); - void push(const void* item); - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - ssize_t insertArrayAt(const void* array, size_t index, size_t length); - ssize_t appendArray(const void* array, size_t length); - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); -}; - -}; // namespace uirenderer -}; // namespace android - -#endif // ANDROID_HWUI_SORTED_LIST_IMPL_H |