BakedOpDispatcherTests.cpp revision aebbbef5658fea13b06586d39adca351135d9edb
1419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik/* 2419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * Copyright (C) 2016 The Android Open Source Project 3419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * 4419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * you may not use this file except in compliance with the License. 6419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * You may obtain a copy of the License at 7419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * 8419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 9419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * 10419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * Unless required by applicable law or agreed to in writing, software 11419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * See the License for the specific language governing permissions and 14419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik * limitations under the License. 15419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik */ 16419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 17419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#include <gtest/gtest.h> 18419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 19419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#include <BakedOpDispatcher.h> 20419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#include <BakedOpRenderer.h> 21284b765e3c1647859d4dac772744e8859c033216sergeyv#include <FrameBuilder.h> 2237413289478a965336239c731ebfea37ac4dde28Chris Craik#include <LayerUpdateQueue.h> 23284b765e3c1647859d4dac772744e8859c033216sergeyv#include <hwui/Paint.h> 2437413289478a965336239c731ebfea37ac4dde28Chris Craik#include <RecordedOp.h> 25419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#include <tests/common/TestUtils.h> 2637413289478a965336239c731ebfea37ac4dde28Chris Craik#include <utils/Color.h> 27419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 2837413289478a965336239c731ebfea37ac4dde28Chris Craik#include <SkBlurDrawLooper.h> 29e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik#include <SkDashPathEffect.h> 30e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 31419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikusing namespace android::uirenderer; 32419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 33419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikstatic BakedOpRenderer::LightInfo sLightInfo; 34284b765e3c1647859d4dac772744e8859c033216sergeyvconst FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50}; 35419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 36419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikclass ValidatingBakedOpRenderer : public BakedOpRenderer { 37419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikpublic: 38419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator) 39419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik : BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo) 40419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik , mValidator(validator) { 41419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik mGlopReceiver = ValidatingGlopReceiver; 42419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik } 43419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikprivate: 44419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik static void ValidatingGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds, 45419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik const ClipBase* clip, const Glop& glop) { 46419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 47419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto vbor = reinterpret_cast<ValidatingBakedOpRenderer*>(&renderer); 48419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik vbor->mValidator(glop); 49419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik } 50419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik std::function<void(const Glop& glop)> mValidator; 51419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik}; 52419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 53284b765e3c1647859d4dac772744e8859c033216sergeyvtypedef void (*TestBakedOpReceiver)(BakedOpRenderer&, const BakedOpState&); 54419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 55419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikstatic void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op, 56aebbbef5658fea13b06586d39adca351135d9edbsergeyv std::function<void(const Glop& glop)> glopVerifier, int expectedGlopCount = 1) { 57419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // Create op, and wrap with basic state. 58419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik LinearAllocator allocator; 5937413289478a965336239c731ebfea37ac4dde28Chris Craik auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 100)); 60419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto state = BakedOpState::tryConstruct(allocator, *snapshot, *op); 61419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ASSERT_NE(nullptr, state); 62419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 63419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik int glopCount = 0; 64aebbbef5658fea13b06586d39adca351135d9edbsergeyv auto glopReceiver = [&glopVerifier, &glopCount, &expectedGlopCount] (const Glop& glop) { 65aebbbef5658fea13b06586d39adca351135d9edbsergeyv ASSERT_LE(glopCount++, expectedGlopCount) << expectedGlopCount << "glop(s) expected"; 66419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik glopVerifier(glop); 67419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik }; 68419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver); 69419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 70419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // Dispatch based on op type created, similar to Frame/LayerBuilder dispatch behavior 71419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#define X(Type) \ 72419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik [](BakedOpRenderer& renderer, const BakedOpState& state) { \ 73419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \ 74419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik }, 75284b765e3c1647859d4dac772744e8859c033216sergeyv static TestBakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X); 76419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#undef X 77419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik unmergedReceivers[op->opId](renderer, *state); 78aebbbef5658fea13b06586d39adca351135d9edbsergeyv ASSERT_EQ(expectedGlopCount, glopCount) << "Exactly " << expectedGlopCount 79aebbbef5658fea13b06586d39adca351135d9edbsergeyv << "Glop(s) expected"; 80419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 81419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 82e98a046d3110eb2ff11a17f4ff27764b803a1379Chris CraikRENDERTHREAD_TEST(BakedOpDispatcher, pathTexture_positionOvalArc) { 83419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik SkPaint strokePaint; 84419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik strokePaint.setStyle(SkPaint::kStroke_Style); 85419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik strokePaint.setStrokeWidth(4); 86e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 87e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik float intervals[] = {1.0f, 1.0f}; 88e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik auto dashEffect = SkDashPathEffect::Create(intervals, 2, 0); 89e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik strokePaint.setPathEffect(dashEffect); 90e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik dashEffect->unref(); 91e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 92e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik auto textureGlopVerifier = [] (const Glop& glop) { 93419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // validate glop produced by renderPathTexture (so texture, unit quad) 94419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto texture = glop.fill.texture.texture; 95419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ASSERT_NE(nullptr, texture); 96419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik float expectedOffset = floor(4 * 1.5f + 0.5f); 97419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik EXPECT_EQ(expectedOffset, reinterpret_cast<PathTexture*>(texture)->offset) 98419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik << "Should see conservative offset from PathCache::computeBounds"; 99419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik Rect expectedBounds(10, 15, 20, 25); 100419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedBounds.outset(expectedOffset); 101e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 102419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik Matrix4 expectedModelView; 103419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedModelView.loadTranslate(10 - expectedOffset, 15 - expectedOffset, 0); 104419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedModelView.scale(10 + 2 * expectedOffset, 10 + 2 * expectedOffset, 1); 105419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik EXPECT_EQ(expectedModelView, glop.transform.modelView) 106419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik << "X and Y offsets, and scale both applied to model view"; 107e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik }; 108e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 109e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik // Arc and Oval will render functionally the same glop, differing only in texture content 110e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik ArcOp arcOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint, 0, 270, true); 111e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik testUnmergedGlopDispatch(renderThread, &arcOp, textureGlopVerifier); 112e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 113e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik OvalOp ovalOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint); 114e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik testUnmergedGlopDispatch(renderThread, &ovalOp, textureGlopVerifier); 115419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 116419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 117419a1e7ef53468e494d21c66ea7f63c0c522d208Chris CraikRENDERTHREAD_TEST(BakedOpDispatcher, onLayerOp_bufferless) { 118419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik SkPaint layerPaint; 119419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik layerPaint.setAlpha(128); 120419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik OffscreenBuffer* buffer = nullptr; // no providing a buffer, should hit rect fallback case 121419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer); 122419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik testUnmergedGlopDispatch(renderThread, &op, [&renderThread] (const Glop& glop) { 123aebbbef5658fea13b06586d39adca351135d9edbsergeyv ADD_FAILURE() << "Nothing should happen"; 124aebbbef5658fea13b06586d39adca351135d9edbsergeyv }, 0); 125419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 12692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 12792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyvstatic int getGlopTransformFlags(renderthread::RenderThread& renderThread, RecordedOp* op) { 12892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv int result = 0; 12992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv testUnmergedGlopDispatch(renderThread, op, [&result] (const Glop& glop) { 13092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv result = glop.transform.transformFlags; 13192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv }); 13292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv return result; 13392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv} 13492a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 13592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyvRENDERTHREAD_TEST(BakedOpDispatcher, offsetFlags) { 13692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv Rect bounds(10, 15, 20, 25); 13792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv SkPaint paint; 13892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv SkPaint aaPaint; 13992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv aaPaint.setAntiAlias(true); 14092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 14192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv RoundRectOp roundRectOp(bounds, Matrix4::identity(), nullptr, &paint, 0, 270); 14292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &roundRectOp)) 14392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for round rect op."; 14492a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 14592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv const float points[4] = {0.5, 0.5, 1.0, 1.0}; 14692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv PointsOp antiAliasedPointsOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4); 14792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedPointsOp)) 14892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for AA points."; 14992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv PointsOp pointsOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4); 15092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &pointsOp)) 15192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect an offset for non-AA points."; 15292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 15392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv LinesOp antiAliasedLinesOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4); 15492a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedLinesOp)) 15592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for AA lines."; 15692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv LinesOp linesOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4); 15792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp)) 15892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect an offset for non-AA lines."; 159284b765e3c1647859d4dac772744e8859c033216sergeyv} 160284b765e3c1647859d4dac772744e8859c033216sergeyv 161284b765e3c1647859d4dac772744e8859c033216sergeyvRENDERTHREAD_TEST(BakedOpDispatcher, renderTextWithShadow) { 162284b765e3c1647859d4dac772744e8859c033216sergeyv auto node = TestUtils::createNode(0, 0, 100, 100, 163284b765e3c1647859d4dac772744e8859c033216sergeyv [](RenderProperties& props, TestCanvas& canvas) { 164284b765e3c1647859d4dac772744e8859c033216sergeyv 165284b765e3c1647859d4dac772744e8859c033216sergeyv android::Paint shadowPaint; 166284b765e3c1647859d4dac772744e8859c033216sergeyv shadowPaint.setColor(SK_ColorRED); 167284b765e3c1647859d4dac772744e8859c033216sergeyv 168284b765e3c1647859d4dac772744e8859c033216sergeyv SkScalar sigma = Blur::convertRadiusToSigma(5); 169284b765e3c1647859d4dac772744e8859c033216sergeyv shadowPaint.setLooper(SkBlurDrawLooper::Create(SK_ColorWHITE, sigma, 3, 3))->unref(); 170284b765e3c1647859d4dac772744e8859c033216sergeyv 171284b765e3c1647859d4dac772744e8859c033216sergeyv TestUtils::drawUtf8ToCanvas(&canvas, "A", shadowPaint, 25, 25); 172284b765e3c1647859d4dac772744e8859c033216sergeyv TestUtils::drawUtf8ToCanvas(&canvas, "B", shadowPaint, 50, 50); 173284b765e3c1647859d4dac772744e8859c033216sergeyv }); 174284b765e3c1647859d4dac772744e8859c033216sergeyv 175284b765e3c1647859d4dac772744e8859c033216sergeyv int glopCount = 0; 176284b765e3c1647859d4dac772744e8859c033216sergeyv auto glopReceiver = [&glopCount] (const Glop& glop) { 177284b765e3c1647859d4dac772744e8859c033216sergeyv if (glopCount < 2) { 178284b765e3c1647859d4dac772744e8859c033216sergeyv // two white shadows 179284b765e3c1647859d4dac772744e8859c033216sergeyv EXPECT_EQ(FloatColor({1, 1, 1, 1}), glop.fill.color); 180284b765e3c1647859d4dac772744e8859c033216sergeyv } else { 181284b765e3c1647859d4dac772744e8859c033216sergeyv // two text draws merged into one, drawn after both shadows 182284b765e3c1647859d4dac772744e8859c033216sergeyv EXPECT_EQ(FloatColor({1, 0, 0, 1}), glop.fill.color); 183284b765e3c1647859d4dac772744e8859c033216sergeyv } 184284b765e3c1647859d4dac772744e8859c033216sergeyv glopCount++; 185284b765e3c1647859d4dac772744e8859c033216sergeyv }; 186284b765e3c1647859d4dac772744e8859c033216sergeyv 187284b765e3c1647859d4dac772744e8859c033216sergeyv ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver); 188284b765e3c1647859d4dac772744e8859c033216sergeyv 189284b765e3c1647859d4dac772744e8859c033216sergeyv FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, 190284b765e3c1647859d4dac772744e8859c033216sergeyv sLightGeometry, Caches::getInstance()); 191284b765e3c1647859d4dac772744e8859c033216sergeyv frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node)); 192284b765e3c1647859d4dac772744e8859c033216sergeyv 193284b765e3c1647859d4dac772744e8859c033216sergeyv frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 194284b765e3c1647859d4dac772744e8859c033216sergeyv ASSERT_EQ(3, glopCount) << "Exactly three glops expected"; 19537413289478a965336239c731ebfea37ac4dde28Chris Craik} 19637413289478a965336239c731ebfea37ac4dde28Chris Craik 19737413289478a965336239c731ebfea37ac4dde28Chris Craikstatic void validateLayerDraw(renderthread::RenderThread& renderThread, 19837413289478a965336239c731ebfea37ac4dde28Chris Craik std::function<void(const Glop& glop)> validator) { 19937413289478a965336239c731ebfea37ac4dde28Chris Craik auto node = TestUtils::createNode(0, 0, 100, 100, 20037413289478a965336239c731ebfea37ac4dde28Chris Craik [](RenderProperties& props, TestCanvas& canvas) { 20137413289478a965336239c731ebfea37ac4dde28Chris Craik props.mutateLayerProperties().setType(LayerType::RenderLayer); 20237413289478a965336239c731ebfea37ac4dde28Chris Craik 20337413289478a965336239c731ebfea37ac4dde28Chris Craik // provide different blend mode, so decoration draws contrast 20437413289478a965336239c731ebfea37ac4dde28Chris Craik props.mutateLayerProperties().setXferMode(SkXfermode::Mode::kSrc_Mode); 20537413289478a965336239c731ebfea37ac4dde28Chris Craik canvas.drawColor(Color::Black, SkXfermode::Mode::kSrcOver_Mode); 20637413289478a965336239c731ebfea37ac4dde28Chris Craik }); 20737413289478a965336239c731ebfea37ac4dde28Chris Craik OffscreenBuffer** layerHandle = node->getLayerHandle(); 20837413289478a965336239c731ebfea37ac4dde28Chris Craik 20937413289478a965336239c731ebfea37ac4dde28Chris Craik auto syncedNode = TestUtils::getSyncedNode(node); 21037413289478a965336239c731ebfea37ac4dde28Chris Craik 21137413289478a965336239c731ebfea37ac4dde28Chris Craik // create RenderNode's layer here in same way prepareTree would 21237413289478a965336239c731ebfea37ac4dde28Chris Craik OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100); 21337413289478a965336239c731ebfea37ac4dde28Chris Craik *layerHandle = &layer; 21437413289478a965336239c731ebfea37ac4dde28Chris Craik { 21537413289478a965336239c731ebfea37ac4dde28Chris Craik LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid 21637413289478a965336239c731ebfea37ac4dde28Chris Craik layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(0, 0, 100, 100)); 21737413289478a965336239c731ebfea37ac4dde28Chris Craik 21837413289478a965336239c731ebfea37ac4dde28Chris Craik ValidatingBakedOpRenderer renderer(renderThread.renderState(), validator); 21937413289478a965336239c731ebfea37ac4dde28Chris Craik FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, 22037413289478a965336239c731ebfea37ac4dde28Chris Craik sLightGeometry, Caches::getInstance()); 22137413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.deferLayers(layerUpdateQueue); 22237413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.deferRenderNode(*syncedNode); 22337413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 22437413289478a965336239c731ebfea37ac4dde28Chris Craik } 22537413289478a965336239c731ebfea37ac4dde28Chris Craik 22637413289478a965336239c731ebfea37ac4dde28Chris Craik // clean up layer pointer, so we can safely destruct RenderNode 22737413289478a965336239c731ebfea37ac4dde28Chris Craik *layerHandle = nullptr; 22837413289478a965336239c731ebfea37ac4dde28Chris Craik} 22937413289478a965336239c731ebfea37ac4dde28Chris Craik 23037413289478a965336239c731ebfea37ac4dde28Chris Craikstatic FloatColor makeFloatColor(uint32_t color) { 23137413289478a965336239c731ebfea37ac4dde28Chris Craik FloatColor c; 23237413289478a965336239c731ebfea37ac4dde28Chris Craik c.set(color); 23337413289478a965336239c731ebfea37ac4dde28Chris Craik return c; 23437413289478a965336239c731ebfea37ac4dde28Chris Craik} 23537413289478a965336239c731ebfea37ac4dde28Chris Craik 23637413289478a965336239c731ebfea37ac4dde28Chris CraikRENDERTHREAD_TEST(BakedOpDispatcher, layerUpdateProperties) { 23737413289478a965336239c731ebfea37ac4dde28Chris Craik for (bool debugOverdraw : { false, true }) { 23837413289478a965336239c731ebfea37ac4dde28Chris Craik for (bool debugLayersUpdates : { false, true }) { 23937413289478a965336239c731ebfea37ac4dde28Chris Craik ScopedProperty<bool> ovdProp(Properties::debugOverdraw, debugOverdraw); 24037413289478a965336239c731ebfea37ac4dde28Chris Craik ScopedProperty<bool> lupProp(Properties::debugLayersUpdates, debugLayersUpdates); 24137413289478a965336239c731ebfea37ac4dde28Chris Craik 24237413289478a965336239c731ebfea37ac4dde28Chris Craik int glopCount = 0; 24337413289478a965336239c731ebfea37ac4dde28Chris Craik validateLayerDraw(renderThread, [&glopCount, &debugLayersUpdates](const Glop& glop) { 24437413289478a965336239c731ebfea37ac4dde28Chris Craik if (glopCount == 0) { 24537413289478a965336239c731ebfea37ac4dde28Chris Craik // 0 - Black layer fill 24637413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 24737413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(makeFloatColor(Color::Black), glop.fill.color); 24837413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount == 1) { 24937413289478a965336239c731ebfea37ac4dde28Chris Craik // 1 - Uncolored (textured) layer draw 25037413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_FALSE(glop.fill.colorEnabled); 25137413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount == 2) { 25237413289478a965336239c731ebfea37ac4dde28Chris Craik // 2 - layer overlay, if present 25337413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 25437413289478a965336239c731ebfea37ac4dde28Chris Craik // blend srcover, different from that of layer 25537413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(GLenum(GL_ONE), glop.blend.src); 25637413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(GLenum(GL_ONE_MINUS_SRC_ALPHA), glop.blend.dst); 25737413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(makeFloatColor(debugLayersUpdates ? 0x7f00ff00 : 0), 25837413289478a965336239c731ebfea37ac4dde28Chris Craik glop.fill.color) << "Should be transparent green if debugLayersUpdates"; 25937413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount < 7) { 26037413289478a965336239c731ebfea37ac4dde28Chris Craik // 3 - 6 - overdraw indicator overlays, if present 26137413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 26237413289478a965336239c731ebfea37ac4dde28Chris Craik uint32_t expectedColor = Caches::getInstance().getOverdrawColor(glopCount - 2); 26337413289478a965336239c731ebfea37ac4dde28Chris Craik ASSERT_EQ(makeFloatColor(expectedColor), glop.fill.color); 26437413289478a965336239c731ebfea37ac4dde28Chris Craik } else { 26537413289478a965336239c731ebfea37ac4dde28Chris Craik ADD_FAILURE() << "Too many glops observed"; 26637413289478a965336239c731ebfea37ac4dde28Chris Craik } 26737413289478a965336239c731ebfea37ac4dde28Chris Craik glopCount++; 26837413289478a965336239c731ebfea37ac4dde28Chris Craik }); 26937413289478a965336239c731ebfea37ac4dde28Chris Craik int expectedCount = 2; 27037413289478a965336239c731ebfea37ac4dde28Chris Craik if (debugLayersUpdates || debugOverdraw) expectedCount++; 27137413289478a965336239c731ebfea37ac4dde28Chris Craik if (debugOverdraw) expectedCount += 4; 27237413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(expectedCount, glopCount); 27337413289478a965336239c731ebfea37ac4dde28Chris Craik } 27437413289478a965336239c731ebfea37ac4dde28Chris Craik } 27537413289478a965336239c731ebfea37ac4dde28Chris Craik} 276