diff options
author | 2016-03-22 15:03:08 -0700 | |
---|---|---|
committer | 2016-03-23 12:55:12 -0700 | |
commit | 3a5811b50157e7ba50854caf957e806aee794d39 (patch) | |
tree | 288fda75463ca914982e43acb7436a5a877f623c | |
parent | 68ffbba158579dd8b6f32aa628ec91228786e864 (diff) |
Precache/early kick off of op work for non-shadow ops.
bug:26562703
bug:27052145
Change-Id: Ic452bfe75da849ffdd47fecdd6eb1472fd0c806e
-rw-r--r-- | libs/hwui/FrameBuilder.cpp | 43 | ||||
-rw-r--r-- | libs/hwui/FrameBuilder.h | 15 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp | 64 | ||||
-rw-r--r-- | libs/hwui/tests/microbench/FrameBuilderBench.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/tests/unit/FrameBuilderTests.cpp | 128 | ||||
-rw-r--r-- | libs/hwui/tests/unit/LeakCheckTests.cpp | 2 |
7 files changed, 178 insertions, 86 deletions
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index dc967e046f11..a992af68c6d2 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -34,7 +34,7 @@ namespace uirenderer { FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, - const LightGeometry& lightGeometry, const Rect &contentDrawBounds, Caches* caches) + const LightGeometry& lightGeometry, const Rect &contentDrawBounds, Caches& caches) : mCanvasState(*this) , mCaches(caches) , mLightRadius(lightGeometry.radius) { @@ -364,15 +364,13 @@ void FrameBuilder::deferShadow(const RenderNodeOp& casterNodeOp) { casterPath = frameAllocatedPath; } - if (CC_LIKELY(!mCanvasState.getRenderTargetClipBounds().isEmpty())) { Matrix4 shadowMatrixXY(casterNodeOp.localMatrix); Matrix4 shadowMatrixZ(casterNodeOp.localMatrix); node.applyViewPropertyTransforms(shadowMatrixXY, false); node.applyViewPropertyTransforms(shadowMatrixZ, true); - LOG_ALWAYS_FATAL_IF(!mCaches, "Caches needed for shadows"); - sp<TessellationCache::ShadowTask> task = mCaches->tessellationCache.getShadowTask( + sp<TessellationCache::ShadowTask> task = mCaches.tessellationCache.getShadowTask( mCanvasState.currentTransform(), mCanvasState.getLocalClipBounds(), casterAlpha >= 1.0f, @@ -483,13 +481,14 @@ void FrameBuilder::deferRenderNodeOp(const RenderNodeOp& op) { * Defers an unmergeable, strokeable op, accounting correctly * for paint's style on the bounds being computed. */ -void FrameBuilder::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, +const BakedOpState* FrameBuilder::deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior) { // Note: here we account for stroke when baking the op BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct( mAllocator, *mCanvasState.writableSnapshot(), op, strokeBehavior); - if (!bakedState) return; // quick rejected + if (!bakedState) return nullptr; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId); + return bakedState; } /** @@ -607,7 +606,10 @@ void FrameBuilder::deferPatchOp(const PatchOp& op) { } void FrameBuilder::deferPathOp(const PathOp& op) { - deferStrokeableOp(op, OpBatchType::Bitmap); + auto state = deferStrokeableOp(op, OpBatchType::AlphaMaskTexture); + if (CC_LIKELY(state)) { + mCaches.pathCache.precache(op.path, op.paint); + } } void FrameBuilder::deferPointsOp(const PointsOp& op) { @@ -620,7 +622,12 @@ void FrameBuilder::deferRectOp(const RectOp& op) { } void FrameBuilder::deferRoundRectOp(const RoundRectOp& op) { - deferStrokeableOp(op, tessBatchId(op)); + auto state = deferStrokeableOp(op, tessBatchId(op)); + if (CC_LIKELY(state && !op.paint->getPathEffect())) { + // TODO: consider storing tessellation task in BakedOpState + mCaches.tessellationCache.precacheRoundRect(state->computedState.transform, *(op.paint), + op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.rx, op.ry); + } } void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) { @@ -660,12 +667,28 @@ void FrameBuilder::deferTextOp(const TextOp& op) { } else { currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId); } + + FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(); + auto& totalTransform = bakedState->computedState.transform; + if (totalTransform.isPureTranslate() || totalTransform.isPerspective()) { + fontRenderer.precache(op.paint, op.glyphs, op.glyphCount, SkMatrix::I()); + } else { + // Partial transform case, see BakedOpDispatcher::renderTextOp + float sx, sy; + totalTransform.decomposeScale(sx, sy); + fontRenderer.precache(op.paint, op.glyphs, op.glyphCount, SkMatrix::MakeScale( + roundf(std::max(1.0f, sx)), + roundf(std::max(1.0f, sy)))); + } } void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) { BakedOpState* bakedState = tryBakeUnboundedOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint))); + + mCaches.fontRenderer.getFontRenderer().precache( + op.paint, op.glyphs, op.glyphCount, SkMatrix::I()); } void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) { @@ -826,5 +849,9 @@ void FrameBuilder::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignore } } +void FrameBuilder::finishDefer() { + mCaches.fontRenderer.endPrecaching(); +} + } // namespace uirenderer } // namespace android diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h index 8a00d336dc08..0b7a6062456a 100644 --- a/libs/hwui/FrameBuilder.h +++ b/libs/hwui/FrameBuilder.h @@ -65,14 +65,16 @@ public: uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const LightGeometry& lightGeometry, - Caches* caches) - : FrameBuilder(layers, clip, viewportWidth, viewportHeight, nodes, lightGeometry, Rect(), caches) {} + Caches& caches) + : FrameBuilder(layers, clip, viewportWidth, viewportHeight, + nodes, lightGeometry, Rect(), caches) {} FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight, const std::vector< sp<RenderNode> >& nodes, const LightGeometry& lightGeometry, - const Rect &contentDrawBounds, Caches* caches); + const Rect &contentDrawBounds, + Caches& caches); virtual ~FrameBuilder() {} @@ -81,10 +83,10 @@ public: * * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use * state->op->opId to lookup a receiver that will be called when the op is replayed. - * */ template <typename StaticDispatcher, typename Renderer> void replayBakedOps(Renderer& renderer) { + finishDefer(); /** * Defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to * dispatch the op via a method on a static dispatcher when the op is replayed. @@ -157,6 +159,7 @@ public: virtual GLuint getTargetFbo() const override { return 0; } private: + void finishDefer(); enum class ChildrenSelectMode { Negative, Positive @@ -198,7 +201,7 @@ private: return mAllocator.create<SkPath>(); } - void deferStrokeableOp(const RecordedOp& op, batchid_t batchId, + const BakedOpState* deferStrokeableOp(const RecordedOp& op, batchid_t batchId, BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined); /** @@ -230,7 +233,7 @@ private: CanvasState mCanvasState; - Caches* mCaches = nullptr; + Caches& mCaches; float mLightRadius; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 31eec8cf3173..eee527881a6a 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -345,10 +345,10 @@ void CanvasContext::draw() { mEglManager.damageFrame(frame, dirty); #if HWUI_NEW_OPS + auto& caches = Caches::getInstance(); FrameBuilder frameBuilder(mLayerUpdateQueue, dirty, frame.width(), frame.height(), - mRenderNodes, mLightGeometry, mContentDrawBounds, &Caches::getInstance()); + mRenderNodes, mLightGeometry, mContentDrawBounds, caches); mLayerUpdateQueue.clear(); - auto&& caches = Caches::getInstance(); BakedOpRenderer renderer(caches, mRenderThread.renderState(), mOpaque, mLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp new file mode 100644 index 000000000000..52039efc6d71 --- /dev/null +++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp @@ -0,0 +1,64 @@ +/* + * 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 "TestSceneBase.h" +#include "utils/Color.h" + +#include <minikin/Layout.h> +#include <hwui/Paint.h> + +#include <cstdio> + +class GlyphStressAnimation; + +static TestScene::Registrar _GlyphStress(TestScene::Info{ + "glyphstress", + "A stress test for both the glyph cache, and glyph rendering.", + TestScene::simpleCreateScene<GlyphStressAnimation> +}); + +class GlyphStressAnimation : public TestScene { +public: + sp<RenderNode> container; + void createContent(int width, int height, TestCanvas& canvas) override { + container = TestUtils::createNode(0, 0, width, height, nullptr); + doFrame(0); // update container + + canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode); + canvas.drawRenderNode(container.get()); + } + + void doFrame(int frameNr) override { + std::unique_ptr<uint16_t[]> text = TestUtils::utf8ToUtf16( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + ssize_t textLength = 26 * 2; + + TestCanvas canvas( + container->stagingProperties().getWidth(), + container->stagingProperties().getHeight()); + Paint paint; + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + paint.setAntiAlias(true); + paint.setColor(Color::Black); + for (int i = 0; i < 5; i++) { + paint.setTextSize(10 + (frameNr % 20) + i * 20); + canvas.drawText(text.get(), 0, textLength, textLength, + 0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr); + } + + container->setStagingDisplayList(canvas.finishRecording()); + } +}; diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp index 7816f0fbf864..9daf6334b507 100644 --- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp +++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp @@ -65,7 +65,7 @@ void BM_FrameBuilder_defer(benchmark::State& state) { auto nodes = createTestNodeList(); while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, - nodes, sLightGeometry, nullptr); + nodes, sLightGeometry, Caches::getInstance()); benchmark::DoNotOptimize(&frameBuilder); } } @@ -80,7 +80,7 @@ void BM_FrameBuilder_deferAndRender(benchmark::State& state) { while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, - nodes, sLightGeometry, nullptr); + nodes, sLightGeometry, Caches::getInstance()); BakedOpRenderer renderer(caches, renderState, true, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); @@ -119,7 +119,7 @@ void BM_FrameBuilder_defer_scene(benchmark::State& state) { while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, - nodes, sLightGeometry, nullptr); + nodes, sLightGeometry, Caches::getInstance()); benchmark::DoNotOptimize(&frameBuilder); } } @@ -137,7 +137,7 @@ void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) { while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, - nodes, sLightGeometry, nullptr); + nodes, sLightGeometry, Caches::getInstance()); BakedOpRenderer renderer(caches, renderState, true, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp index a467b5c15560..0aabfb1f1f34 100644 --- a/libs/hwui/tests/unit/FrameBuilderTests.cpp +++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp @@ -107,7 +107,7 @@ public: class FailRenderer : public TestRendererBase {}; -TEST(FrameBuilder, simple) { +RENDERTHREAD_TEST(FrameBuilder, simple) { class SimpleTestRenderer : public TestRendererBase { public: void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override { @@ -133,13 +133,13 @@ TEST(FrameBuilder, simple) { canvas.drawBitmap(bitmap, 10, 10, nullptr); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SimpleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); // 2 ops + start + end } -TEST(FrameBuilder, simpleStroke) { +RENDERTHREAD_TEST(FrameBuilder, simpleStroke) { class SimpleStrokeTestRenderer : public TestRendererBase { public: void onPointsOp(const PointsOp& op, const BakedOpState& state) override { @@ -159,13 +159,13 @@ TEST(FrameBuilder, simpleStroke) { canvas.drawPoint(50, 50, strokedPaint); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SimpleStrokeTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(1, renderer.getIndex()); } -TEST(FrameBuilder, simpleRejection) { +RENDERTHREAD_TEST(FrameBuilder, simpleRejection) { auto node = TestUtils::createNode(0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) { canvas.save(SaveFlags::MatrixClip); @@ -174,13 +174,13 @@ TEST(FrameBuilder, simpleRejection) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); FailRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); } -TEST(FrameBuilder, simpleBatching) { +RENDERTHREAD_TEST(FrameBuilder, simpleBatching) { const int LOOPS = 5; class SimpleBatchingTestRenderer : public TestRendererBase { public: @@ -209,14 +209,14 @@ TEST(FrameBuilder, simpleBatching) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SimpleBatchingTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2 * LOOPS, renderer.getIndex()) << "Expect number of ops = 2 * loop count"; } -TEST(FrameBuilder, clippedMerging) { +RENDERTHREAD_TEST(FrameBuilder, clippedMerging) { class ClippedMergingTestRenderer : public TestRendererBase { public: void onMergedBitmapOps(const MergedBakedOpList& opList) override { @@ -250,13 +250,13 @@ TEST(FrameBuilder, clippedMerging) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); ClippedMergingTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); } -TEST(FrameBuilder, textMerging) { +RENDERTHREAD_TEST(FrameBuilder, textMerging) { class TextMergingTestRenderer : public TestRendererBase { public: void onMergedTextOps(const MergedBakedOpList& opList) override { @@ -278,13 +278,13 @@ TEST(FrameBuilder, textMerging) { TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); TextMergingTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2, renderer.getIndex()) << "Expect 2 ops"; } -TEST(FrameBuilder, textStrikethrough) { +RENDERTHREAD_TEST(FrameBuilder, textStrikethrough) { const int LOOPS = 5; class TextStrikethroughTestRenderer : public TestRendererBase { public: @@ -309,7 +309,7 @@ TEST(FrameBuilder, textStrikethrough) { } }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 2000), 200, 2000, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); TextStrikethroughTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2 * LOOPS, renderer.getIndex()) @@ -319,7 +319,7 @@ TEST(FrameBuilder, textStrikethrough) { static auto styles = { SkPaint::kFill_Style, SkPaint::kStroke_Style, SkPaint::kStrokeAndFill_Style }; -TEST(FrameBuilder, textStyle) { +RENDERTHREAD_TEST(FrameBuilder, textStyle) { class TextStyleTestRenderer : public TestRendererBase { public: void onMergedTextOps(const MergedBakedOpList& opList) override { @@ -365,7 +365,7 @@ TEST(FrameBuilder, textStyle) { } }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); TextStyleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(3, renderer.getIndex()) << "Expect 3 ops"; @@ -398,13 +398,13 @@ RENDERTHREAD_TEST(FrameBuilder, textureLayer) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); TextureLayerTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(1, renderer.getIndex()); } -TEST(FrameBuilder, functor_reject) { +RENDERTHREAD_TEST(FrameBuilder, functor_reject) { class FunctorTestRenderer : public TestRendererBase { public: void onFunctorOp(const FunctorOp& op, const BakedOpState& state) override { @@ -421,13 +421,14 @@ TEST(FrameBuilder, functor_reject) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(scrolledFunctorView), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(scrolledFunctorView), + sLightGeometry, Caches::getInstance()); FunctorTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected"; } -TEST(FrameBuilder, renderNode) { +RENDERTHREAD_TEST(FrameBuilder, renderNode) { class RenderNodeTestRenderer : public TestRendererBase { public: void onRectOp(const RectOp& op, const BakedOpState& state) override { @@ -466,13 +467,13 @@ TEST(FrameBuilder, renderNode) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(parent), sLightGeometry, Caches::getInstance()); RenderNodeTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2, renderer.getIndex()); } -TEST(FrameBuilder, clipped) { +RENDERTHREAD_TEST(FrameBuilder, clipped) { class ClippedTestRenderer : public TestRendererBase { public: void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override { @@ -491,12 +492,12 @@ TEST(FrameBuilder, clipped) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver - 200, 200, TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + 200, 200, TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); ClippedTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); } -TEST(FrameBuilder, saveLayer_simple) { +RENDERTHREAD_TEST(FrameBuilder, saveLayer_simple) { class SaveLayerSimpleTestRenderer : public TestRendererBase { public: OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override { @@ -533,13 +534,13 @@ TEST(FrameBuilder, saveLayer_simple) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerSimpleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); } -TEST(FrameBuilder, saveLayer_nested) { +RENDERTHREAD_TEST(FrameBuilder, saveLayer_nested) { /* saveLayer1 { rect1, saveLayer2 { rect2 } } will play back as: * - startTemporaryLayer2, rect2 endLayer2 * - startTemporaryLayer1, rect1, drawLayer2, endLayer1 @@ -605,13 +606,13 @@ TEST(FrameBuilder, saveLayer_nested) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(800, 800), 800, 800, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerNestedTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(10, renderer.getIndex()); } -TEST(FrameBuilder, saveLayer_contentRejection) { +RENDERTHREAD_TEST(FrameBuilder, saveLayer_contentRejection) { auto node = TestUtils::createNode(0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) { canvas.save(SaveFlags::MatrixClip); @@ -625,14 +626,14 @@ TEST(FrameBuilder, saveLayer_contentRejection) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); FailRenderer renderer; // should see no ops, even within the layer, since the layer should be rejected frameBuilder.replayBakedOps<TestDispatcher>(renderer); } -TEST(FrameBuilder, saveLayerUnclipped_simple) { +RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_simple) { class SaveLayerUnclippedSimpleTestRenderer : public TestRendererBase { public: void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override { @@ -668,13 +669,13 @@ TEST(FrameBuilder, saveLayerUnclipped_simple) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerUnclippedSimpleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); } -TEST(FrameBuilder, saveLayerUnclipped_mergedClears) { +RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_mergedClears) { class SaveLayerUnclippedMergedClearsTestRenderer : public TestRendererBase { public: void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override { @@ -722,14 +723,14 @@ TEST(FrameBuilder, saveLayerUnclipped_mergedClears) { canvas.restoreToCount(restoreTo); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerUnclippedMergedClearsTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(10, renderer.getIndex()) << "Expect 4 copyTos, 4 copyFroms, 1 clear SimpleRects, and 1 rect."; } -TEST(FrameBuilder, saveLayerUnclipped_clearClip) { +RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_clearClip) { class SaveLayerUnclippedClearClipTestRenderer : public TestRendererBase { public: void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override { @@ -763,13 +764,13 @@ TEST(FrameBuilder, saveLayerUnclipped_clearClip) { // draw with partial screen dirty, and assert we see that rect later FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeLTRB(50, 50, 150, 150), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerUnclippedClearClipTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); } -TEST(FrameBuilder, saveLayerUnclipped_reject) { +RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_reject) { auto node = TestUtils::createNode(0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) { // unclipped savelayer + rect both in area that won't intersect with dirty @@ -780,7 +781,7 @@ TEST(FrameBuilder, saveLayerUnclipped_reject) { // draw with partial screen dirty that doesn't intersect with savelayer FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); FailRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); } @@ -789,7 +790,7 @@ TEST(FrameBuilder, saveLayerUnclipped_reject) { * - startTemporaryLayer, onCopyToLayer, onSimpleRects, onRect, onCopyFromLayer, endLayer * - startFrame, onCopyToLayer, onSimpleRects, drawLayer, onCopyFromLayer, endframe */ -TEST(FrameBuilder, saveLayerUnclipped_complex) { +RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_complex) { class SaveLayerUnclippedComplexTestRenderer : public TestRendererBase { public: OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) { @@ -840,7 +841,7 @@ TEST(FrameBuilder, saveLayerUnclipped_complex) { canvas.restore(); }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(600, 600), 600, 600, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerUnclippedComplexTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(12, renderer.getIndex()); @@ -898,7 +899,7 @@ RENDERTHREAD_TEST(FrameBuilder, hwLayer_simple) { layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(25, 25, 75, 75)); FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - syncedNodeList, sLightGeometry, nullptr); + syncedNodeList, sLightGeometry, Caches::getInstance()); HwLayerSimpleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(6, renderer.getIndex()); @@ -999,7 +1000,7 @@ RENDERTHREAD_TEST(FrameBuilder, hwLayer_complex) { layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(200, 200)); FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - syncedList, sLightGeometry, nullptr); + syncedList, sLightGeometry, Caches::getInstance()); HwLayerComplexTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(13, renderer.getIndex()); @@ -1023,7 +1024,7 @@ static void drawOrderedNode(RecordingCanvas* canvas, uint8_t expectedDrawOrder, node->setPropertyFieldsDirty(RenderNode::TRANSLATION_Z); canvas->drawRenderNode(node.get()); // canvas takes reference/sole ownership } -TEST(FrameBuilder, zReorder) { +RENDERTHREAD_TEST(FrameBuilder, zReorder) { class ZReorderTestRenderer : public TestRendererBase { public: void onRectOp(const RectOp& op, const BakedOpState& state) override { @@ -1048,13 +1049,13 @@ TEST(FrameBuilder, zReorder) { drawOrderedNode(&canvas, 9, -10.0f); // in reorder=false at this point, so played inorder }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100, - TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(parent), sLightGeometry, Caches::getInstance()); ZReorderTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(10, renderer.getIndex()); }; -TEST(FrameBuilder, projectionReorder) { +RENDERTHREAD_TEST(FrameBuilder, projectionReorder) { static const int scrollX = 5; static const int scrollY = 10; class ProjectionReorderTestRenderer : public TestRendererBase { @@ -1139,7 +1140,7 @@ TEST(FrameBuilder, projectionReorder) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100, - TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(parent), sLightGeometry, Caches::getInstance()); ProjectionReorderTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(3, renderer.getIndex()); @@ -1222,7 +1223,7 @@ RENDERTHREAD_TEST(FrameBuilder, projectionHwLayer) { LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(200, 200)); FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, - syncedList, sLightGeometry, nullptr); + syncedList, sLightGeometry, Caches::getInstance()); ProjectionHwLayerTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(6, renderer.getIndex()); @@ -1278,7 +1279,7 @@ RENDERTHREAD_TEST(FrameBuilder, projectionChildScroll) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400, - TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(parent), sLightGeometry, Caches::getInstance()); ProjectionChildScrollTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2, renderer.getIndex()); @@ -1321,7 +1322,7 @@ RENDERTHREAD_TEST(FrameBuilder, shadow) { }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(parent), sLightGeometry, &Caches::getInstance()); + TestUtils::createSyncedNodeList(parent), sLightGeometry, Caches::getInstance()); ShadowTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(2, renderer.getIndex()); @@ -1363,8 +1364,7 @@ RENDERTHREAD_TEST(FrameBuilder, shadowSaveLayer) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, TestUtils::createSyncedNodeList(parent), - (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 50}, - &Caches::getInstance()); + (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 50}, Caches::getInstance()); ShadowSaveLayerTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(5, renderer.getIndex()); @@ -1416,8 +1416,7 @@ RENDERTHREAD_TEST(FrameBuilder, shadowHwLayer) { layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(100, 100)); FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, syncedList, - (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 30}, - &Caches::getInstance()); + (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 30}, Caches::getInstance()); ShadowHwLayerTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(5, renderer.getIndex()); @@ -1426,7 +1425,7 @@ RENDERTHREAD_TEST(FrameBuilder, shadowHwLayer) { *layerHandle = nullptr; } -TEST(FrameBuilder, shadowLayering) { +RENDERTHREAD_TEST(FrameBuilder, shadowLayering) { class ShadowLayeringTestRenderer : public TestRendererBase { public: void onShadowOp(const ShadowOp& op, const BakedOpState& state) override { @@ -1447,8 +1446,7 @@ TEST(FrameBuilder, shadowLayering) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, TestUtils::createSyncedNodeList(parent), - (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 50}, - &Caches::getInstance()); + (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 50}, Caches::getInstance()); ShadowLayeringTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(4, renderer.getIndex()); @@ -1476,13 +1474,13 @@ static void testProperty(std::function<void(RenderProperties&)> propSetupCallbac }); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); PropertyTestRenderer renderer(opValidateCallback); frameBuilder.replayBakedOps<TestDispatcher>(renderer); EXPECT_EQ(1, renderer.getIndex()) << "Should have seen one op"; } -TEST(FrameBuilder, renderPropOverlappingRenderingAlpha) { +RENDERTHREAD_TEST(FrameBuilder, renderPropOverlappingRenderingAlpha) { testProperty([](RenderProperties& properties) { properties.setAlpha(0.5f); properties.setHasOverlappingRendering(false); @@ -1491,7 +1489,7 @@ TEST(FrameBuilder, renderPropOverlappingRenderingAlpha) { }); } -TEST(FrameBuilder, renderPropClipping) { +RENDERTHREAD_TEST(FrameBuilder, renderPropClipping) { testProperty([](RenderProperties& properties) { properties.setClipToBounds(true); properties.setClipBounds(Rect(10, 20, 300, 400)); @@ -1501,7 +1499,7 @@ TEST(FrameBuilder, renderPropClipping) { }); } -TEST(FrameBuilder, renderPropRevealClip) { +RENDERTHREAD_TEST(FrameBuilder, renderPropRevealClip) { testProperty([](RenderProperties& properties) { properties.mutableRevealClip().set(true, 50, 50, 25); }, [](const RectOp& op, const BakedOpState& state) { @@ -1512,7 +1510,7 @@ TEST(FrameBuilder, renderPropRevealClip) { }); } -TEST(FrameBuilder, renderPropOutlineClip) { +RENDERTHREAD_TEST(FrameBuilder, renderPropOutlineClip) { testProperty([](RenderProperties& properties) { properties.mutableOutline().setShouldClip(true); properties.mutableOutline().setRoundRect(10, 20, 30, 40, 5.0f, 0.5f); @@ -1524,7 +1522,7 @@ TEST(FrameBuilder, renderPropOutlineClip) { }); } -TEST(FrameBuilder, renderPropTransform) { +RENDERTHREAD_TEST(FrameBuilder, renderPropTransform) { testProperty([](RenderProperties& properties) { properties.setLeftTopRightBottom(10, 10, 110, 110); @@ -1618,7 +1616,7 @@ void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData, auto nodes = TestUtils::createSyncedNodeList(node); // sync before querying height FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - nodes, sLightGeometry, nullptr); + nodes, sLightGeometry, Caches::getInstance()); SaveLayerAlphaClipTestRenderer renderer(outObservedData); frameBuilder.replayBakedOps<TestDispatcher>(renderer); @@ -1626,7 +1624,7 @@ void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData, ASSERT_EQ(4, renderer.getIndex()) << "Test must trigger saveLayer alpha behavior."; } -TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) { +RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) { SaveLayerAlphaData observedData; testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) { properties.setTranslationX(10); // offset rendering content @@ -1642,7 +1640,7 @@ TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) { << "expect content to be translated as part of being clipped"; } -TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) { +RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) { SaveLayerAlphaData observedData; testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) { // Translate and rotate the view so that the only visible part is the top left corner of @@ -1661,7 +1659,7 @@ TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) { EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix); } -TEST(FrameBuilder, renderPropSaveLayerAlphaScale) { +RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaScale) { SaveLayerAlphaData observedData; testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) { properties.setPivotX(0); diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp index da786c7d9d46..9161f90b54aa 100644 --- a/libs/hwui/tests/unit/LeakCheckTests.cpp +++ b/libs/hwui/tests/unit/LeakCheckTests.cpp @@ -41,7 +41,7 @@ RENDERTHREAD_TEST(LeakCheck, saveLayerUnclipped_simple) { Caches& caches = Caches::getInstance(); FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, - TestUtils::createSyncedNodeList(node), sLightGeometery, nullptr); + TestUtils::createSyncedNodeList(node), sLightGeometery, Caches::getInstance()); BakedOpRenderer renderer(caches, renderState, true, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); } |