BakedOpDispatcherTests.cpp revision 07ae505d4045e2b1ae501e87560984dae06f9dd8
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> 3089561e6e4201aebc78a76ac055071ad2149db704sergeyv#include <SkPath.h> 31e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 32419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikusing namespace android::uirenderer; 33419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 34419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikstatic BakedOpRenderer::LightInfo sLightInfo; 35284b765e3c1647859d4dac772744e8859c033216sergeyvconst FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50}; 36419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 37419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikclass ValidatingBakedOpRenderer : public BakedOpRenderer { 38419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikpublic: 39419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator) 4007ae505d4045e2b1ae501e87560984dae06f9dd8Romain Guy : BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo) 41419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik , mValidator(validator) { 42419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik mGlopReceiver = ValidatingGlopReceiver; 43419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik } 44419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikprivate: 45419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik static void ValidatingGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds, 46419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik const ClipBase* clip, const Glop& glop) { 47419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 48419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto vbor = reinterpret_cast<ValidatingBakedOpRenderer*>(&renderer); 49419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik vbor->mValidator(glop); 50419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik } 51419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik std::function<void(const Glop& glop)> mValidator; 52419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik}; 53419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 54284b765e3c1647859d4dac772744e8859c033216sergeyvtypedef void (*TestBakedOpReceiver)(BakedOpRenderer&, const BakedOpState&); 55419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 56419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikstatic void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op, 57aebbbef5658fea13b06586d39adca351135d9edbsergeyv std::function<void(const Glop& glop)> glopVerifier, int expectedGlopCount = 1) { 58419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // Create op, and wrap with basic state. 59419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik LinearAllocator allocator; 6037413289478a965336239c731ebfea37ac4dde28Chris Craik auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 100)); 61419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto state = BakedOpState::tryConstruct(allocator, *snapshot, *op); 62419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ASSERT_NE(nullptr, state); 63419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 64419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik int glopCount = 0; 65aebbbef5658fea13b06586d39adca351135d9edbsergeyv auto glopReceiver = [&glopVerifier, &glopCount, &expectedGlopCount] (const Glop& glop) { 66aebbbef5658fea13b06586d39adca351135d9edbsergeyv ASSERT_LE(glopCount++, expectedGlopCount) << expectedGlopCount << "glop(s) expected"; 67419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik glopVerifier(glop); 68419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik }; 69419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver); 70419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 71419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // Dispatch based on op type created, similar to Frame/LayerBuilder dispatch behavior 72419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#define X(Type) \ 73419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik [](BakedOpRenderer& renderer, const BakedOpState& state) { \ 74419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \ 75419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik }, 76284b765e3c1647859d4dac772744e8859c033216sergeyv static TestBakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X); 77419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#undef X 78419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik unmergedReceivers[op->opId](renderer, *state); 79aebbbef5658fea13b06586d39adca351135d9edbsergeyv ASSERT_EQ(expectedGlopCount, glopCount) << "Exactly " << expectedGlopCount 80aebbbef5658fea13b06586d39adca351135d9edbsergeyv << "Glop(s) expected"; 81419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 82419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 8398c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, pathTexture_positionOvalArc) { 84419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik SkPaint strokePaint; 85419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik strokePaint.setStyle(SkPaint::kStroke_Style); 86419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik strokePaint.setStrokeWidth(4); 87e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 88e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik float intervals[] = {1.0f, 1.0f}; 89260ab726486317496bc12a57d599ea96dcde3284Mike Reed strokePaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0)); 90e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 91e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik auto textureGlopVerifier = [] (const Glop& glop) { 92419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik // validate glop produced by renderPathTexture (so texture, unit quad) 93419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik auto texture = glop.fill.texture.texture; 94419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik ASSERT_NE(nullptr, texture); 95419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik float expectedOffset = floor(4 * 1.5f + 0.5f); 96419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik EXPECT_EQ(expectedOffset, reinterpret_cast<PathTexture*>(texture)->offset) 97419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik << "Should see conservative offset from PathCache::computeBounds"; 98419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik Rect expectedBounds(10, 15, 20, 25); 99419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedBounds.outset(expectedOffset); 100e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 101419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik Matrix4 expectedModelView; 102419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedModelView.loadTranslate(10 - expectedOffset, 15 - expectedOffset, 0); 103419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik expectedModelView.scale(10 + 2 * expectedOffset, 10 + 2 * expectedOffset, 1); 104419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik EXPECT_EQ(expectedModelView, glop.transform.modelView) 105419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik << "X and Y offsets, and scale both applied to model view"; 106e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik }; 107e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 108e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik // Arc and Oval will render functionally the same glop, differing only in texture content 109e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik ArcOp arcOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint, 0, 270, true); 110e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik testUnmergedGlopDispatch(renderThread, &arcOp, textureGlopVerifier); 111e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik 112e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik OvalOp ovalOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint); 113e98a046d3110eb2ff11a17f4ff27764b803a1379Chris Craik testUnmergedGlopDispatch(renderThread, &ovalOp, textureGlopVerifier); 114419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 115419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik 11698c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, onLayerOp_bufferless) { 117419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik SkPaint layerPaint; 118419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik layerPaint.setAlpha(128); 119419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik OffscreenBuffer* buffer = nullptr; // no providing a buffer, should hit rect fallback case 120419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer); 121b2233821e1a7d34af816c85e00ab110935175c0fYi Kong testUnmergedGlopDispatch(renderThread, &op, [] (const Glop& glop) { 122aebbbef5658fea13b06586d39adca351135d9edbsergeyv ADD_FAILURE() << "Nothing should happen"; 123aebbbef5658fea13b06586d39adca351135d9edbsergeyv }, 0); 124419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik} 12592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 12692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyvstatic int getGlopTransformFlags(renderthread::RenderThread& renderThread, RecordedOp* op) { 12792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv int result = 0; 12892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv testUnmergedGlopDispatch(renderThread, op, [&result] (const Glop& glop) { 12992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv result = glop.transform.transformFlags; 13092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv }); 13192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv return result; 13292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv} 13392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 13498c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, offsetFlags) { 13592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv Rect bounds(10, 15, 20, 25); 13692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv SkPaint paint; 13792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv SkPaint aaPaint; 13892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv aaPaint.setAntiAlias(true); 13992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 14092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv RoundRectOp roundRectOp(bounds, Matrix4::identity(), nullptr, &paint, 0, 270); 14192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &roundRectOp)) 14292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for round rect op."; 14392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 14492a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv const float points[4] = {0.5, 0.5, 1.0, 1.0}; 14592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv PointsOp antiAliasedPointsOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4); 14692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedPointsOp)) 14792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for AA points."; 14892a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv PointsOp pointsOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4); 14992a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &pointsOp)) 15092a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect an offset for non-AA points."; 15192a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv 15292a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv LinesOp antiAliasedLinesOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4); 15392a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedLinesOp)) 15492a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect no offset for AA lines."; 15592a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv LinesOp linesOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4); 15692a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp)) 15792a5d4b99a5554adca0e94627d44d2bd7f4f0bc0sergeyv << "Expect an offset for non-AA lines."; 158284b765e3c1647859d4dac772744e8859c033216sergeyv} 159284b765e3c1647859d4dac772744e8859c033216sergeyv 16098c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, renderTextWithShadow) { 16106152cdd06da50762716cd455dcf7ab0117f25b0Stan Iliev auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100, 16206152cdd06da50762716cd455dcf7ab0117f25b0Stan Iliev [](RenderProperties& props, RecordingCanvas& canvas) { 163284b765e3c1647859d4dac772744e8859c033216sergeyv 164284b765e3c1647859d4dac772744e8859c033216sergeyv android::Paint shadowPaint; 165284b765e3c1647859d4dac772744e8859c033216sergeyv shadowPaint.setColor(SK_ColorRED); 166284b765e3c1647859d4dac772744e8859c033216sergeyv 167284b765e3c1647859d4dac772744e8859c033216sergeyv SkScalar sigma = Blur::convertRadiusToSigma(5); 168260ab726486317496bc12a57d599ea96dcde3284Mike Reed shadowPaint.setLooper(SkBlurDrawLooper::Make(SK_ColorWHITE, sigma, 3, 3)); 169284b765e3c1647859d4dac772744e8859c033216sergeyv 170284b765e3c1647859d4dac772744e8859c033216sergeyv TestUtils::drawUtf8ToCanvas(&canvas, "A", shadowPaint, 25, 25); 171284b765e3c1647859d4dac772744e8859c033216sergeyv TestUtils::drawUtf8ToCanvas(&canvas, "B", shadowPaint, 50, 50); 172284b765e3c1647859d4dac772744e8859c033216sergeyv }); 173284b765e3c1647859d4dac772744e8859c033216sergeyv 174284b765e3c1647859d4dac772744e8859c033216sergeyv int glopCount = 0; 175284b765e3c1647859d4dac772744e8859c033216sergeyv auto glopReceiver = [&glopCount] (const Glop& glop) { 176284b765e3c1647859d4dac772744e8859c033216sergeyv if (glopCount < 2) { 177284b765e3c1647859d4dac772744e8859c033216sergeyv // two white shadows 178284b765e3c1647859d4dac772744e8859c033216sergeyv EXPECT_EQ(FloatColor({1, 1, 1, 1}), glop.fill.color); 179284b765e3c1647859d4dac772744e8859c033216sergeyv } else { 180284b765e3c1647859d4dac772744e8859c033216sergeyv // two text draws merged into one, drawn after both shadows 181284b765e3c1647859d4dac772744e8859c033216sergeyv EXPECT_EQ(FloatColor({1, 0, 0, 1}), glop.fill.color); 182284b765e3c1647859d4dac772744e8859c033216sergeyv } 183284b765e3c1647859d4dac772744e8859c033216sergeyv glopCount++; 184284b765e3c1647859d4dac772744e8859c033216sergeyv }; 185284b765e3c1647859d4dac772744e8859c033216sergeyv 186284b765e3c1647859d4dac772744e8859c033216sergeyv ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver); 187284b765e3c1647859d4dac772744e8859c033216sergeyv 188284b765e3c1647859d4dac772744e8859c033216sergeyv FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, 189284b765e3c1647859d4dac772744e8859c033216sergeyv sLightGeometry, Caches::getInstance()); 190284b765e3c1647859d4dac772744e8859c033216sergeyv frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node)); 191284b765e3c1647859d4dac772744e8859c033216sergeyv 192284b765e3c1647859d4dac772744e8859c033216sergeyv frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 193284b765e3c1647859d4dac772744e8859c033216sergeyv ASSERT_EQ(3, glopCount) << "Exactly three glops expected"; 19437413289478a965336239c731ebfea37ac4dde28Chris Craik} 19537413289478a965336239c731ebfea37ac4dde28Chris Craik 19637413289478a965336239c731ebfea37ac4dde28Chris Craikstatic void validateLayerDraw(renderthread::RenderThread& renderThread, 19737413289478a965336239c731ebfea37ac4dde28Chris Craik std::function<void(const Glop& glop)> validator) { 19806152cdd06da50762716cd455dcf7ab0117f25b0Stan Iliev auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100, 19906152cdd06da50762716cd455dcf7ab0117f25b0Stan Iliev [](RenderProperties& props, RecordingCanvas& canvas) { 20037413289478a965336239c731ebfea37ac4dde28Chris Craik props.mutateLayerProperties().setType(LayerType::RenderLayer); 20137413289478a965336239c731ebfea37ac4dde28Chris Craik 20237413289478a965336239c731ebfea37ac4dde28Chris Craik // provide different blend mode, so decoration draws contrast 203260ab726486317496bc12a57d599ea96dcde3284Mike Reed props.mutateLayerProperties().setXferMode(SkBlendMode::kSrc); 204260ab726486317496bc12a57d599ea96dcde3284Mike Reed canvas.drawColor(Color::Black, SkBlendMode::kSrcOver); 20537413289478a965336239c731ebfea37ac4dde28Chris Craik }); 20637413289478a965336239c731ebfea37ac4dde28Chris Craik OffscreenBuffer** layerHandle = node->getLayerHandle(); 20737413289478a965336239c731ebfea37ac4dde28Chris Craik 20837413289478a965336239c731ebfea37ac4dde28Chris Craik auto syncedNode = TestUtils::getSyncedNode(node); 20937413289478a965336239c731ebfea37ac4dde28Chris Craik 21037413289478a965336239c731ebfea37ac4dde28Chris Craik // create RenderNode's layer here in same way prepareTree would 21137413289478a965336239c731ebfea37ac4dde28Chris Craik OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100); 21237413289478a965336239c731ebfea37ac4dde28Chris Craik *layerHandle = &layer; 21337413289478a965336239c731ebfea37ac4dde28Chris Craik { 21437413289478a965336239c731ebfea37ac4dde28Chris Craik LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid 21537413289478a965336239c731ebfea37ac4dde28Chris Craik layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(0, 0, 100, 100)); 21637413289478a965336239c731ebfea37ac4dde28Chris Craik 21737413289478a965336239c731ebfea37ac4dde28Chris Craik ValidatingBakedOpRenderer renderer(renderThread.renderState(), validator); 21837413289478a965336239c731ebfea37ac4dde28Chris Craik FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, 21937413289478a965336239c731ebfea37ac4dde28Chris Craik sLightGeometry, Caches::getInstance()); 22037413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.deferLayers(layerUpdateQueue); 22137413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.deferRenderNode(*syncedNode); 22237413289478a965336239c731ebfea37ac4dde28Chris Craik frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); 22337413289478a965336239c731ebfea37ac4dde28Chris Craik } 22437413289478a965336239c731ebfea37ac4dde28Chris Craik 22537413289478a965336239c731ebfea37ac4dde28Chris Craik // clean up layer pointer, so we can safely destruct RenderNode 22637413289478a965336239c731ebfea37ac4dde28Chris Craik *layerHandle = nullptr; 22737413289478a965336239c731ebfea37ac4dde28Chris Craik} 22837413289478a965336239c731ebfea37ac4dde28Chris Craik 22937413289478a965336239c731ebfea37ac4dde28Chris Craikstatic FloatColor makeFloatColor(uint32_t color) { 23037413289478a965336239c731ebfea37ac4dde28Chris Craik FloatColor c; 23137413289478a965336239c731ebfea37ac4dde28Chris Craik c.set(color); 23237413289478a965336239c731ebfea37ac4dde28Chris Craik return c; 23337413289478a965336239c731ebfea37ac4dde28Chris Craik} 23437413289478a965336239c731ebfea37ac4dde28Chris Craik 23598c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, layerUpdateProperties) { 23637413289478a965336239c731ebfea37ac4dde28Chris Craik for (bool debugOverdraw : { false, true }) { 23737413289478a965336239c731ebfea37ac4dde28Chris Craik for (bool debugLayersUpdates : { false, true }) { 23837413289478a965336239c731ebfea37ac4dde28Chris Craik ScopedProperty<bool> ovdProp(Properties::debugOverdraw, debugOverdraw); 23937413289478a965336239c731ebfea37ac4dde28Chris Craik ScopedProperty<bool> lupProp(Properties::debugLayersUpdates, debugLayersUpdates); 24037413289478a965336239c731ebfea37ac4dde28Chris Craik 24137413289478a965336239c731ebfea37ac4dde28Chris Craik int glopCount = 0; 24237413289478a965336239c731ebfea37ac4dde28Chris Craik validateLayerDraw(renderThread, [&glopCount, &debugLayersUpdates](const Glop& glop) { 24337413289478a965336239c731ebfea37ac4dde28Chris Craik if (glopCount == 0) { 24437413289478a965336239c731ebfea37ac4dde28Chris Craik // 0 - Black layer fill 24537413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 24637413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(makeFloatColor(Color::Black), glop.fill.color); 24737413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount == 1) { 24837413289478a965336239c731ebfea37ac4dde28Chris Craik // 1 - Uncolored (textured) layer draw 24937413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_FALSE(glop.fill.colorEnabled); 25037413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount == 2) { 25137413289478a965336239c731ebfea37ac4dde28Chris Craik // 2 - layer overlay, if present 25237413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 25337413289478a965336239c731ebfea37ac4dde28Chris Craik // blend srcover, different from that of layer 25437413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(GLenum(GL_ONE), glop.blend.src); 25537413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(GLenum(GL_ONE_MINUS_SRC_ALPHA), glop.blend.dst); 25637413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(makeFloatColor(debugLayersUpdates ? 0x7f00ff00 : 0), 25737413289478a965336239c731ebfea37ac4dde28Chris Craik glop.fill.color) << "Should be transparent green if debugLayersUpdates"; 25837413289478a965336239c731ebfea37ac4dde28Chris Craik } else if (glopCount < 7) { 25937413289478a965336239c731ebfea37ac4dde28Chris Craik // 3 - 6 - overdraw indicator overlays, if present 26037413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_TRUE(glop.fill.colorEnabled); 26137413289478a965336239c731ebfea37ac4dde28Chris Craik uint32_t expectedColor = Caches::getInstance().getOverdrawColor(glopCount - 2); 26237413289478a965336239c731ebfea37ac4dde28Chris Craik ASSERT_EQ(makeFloatColor(expectedColor), glop.fill.color); 26337413289478a965336239c731ebfea37ac4dde28Chris Craik } else { 26437413289478a965336239c731ebfea37ac4dde28Chris Craik ADD_FAILURE() << "Too many glops observed"; 26537413289478a965336239c731ebfea37ac4dde28Chris Craik } 26637413289478a965336239c731ebfea37ac4dde28Chris Craik glopCount++; 26737413289478a965336239c731ebfea37ac4dde28Chris Craik }); 26837413289478a965336239c731ebfea37ac4dde28Chris Craik int expectedCount = 2; 26937413289478a965336239c731ebfea37ac4dde28Chris Craik if (debugLayersUpdates || debugOverdraw) expectedCount++; 27037413289478a965336239c731ebfea37ac4dde28Chris Craik if (debugOverdraw) expectedCount += 4; 27137413289478a965336239c731ebfea37ac4dde28Chris Craik EXPECT_EQ(expectedCount, glopCount); 27237413289478a965336239c731ebfea37ac4dde28Chris Craik } 27337413289478a965336239c731ebfea37ac4dde28Chris Craik } 27437413289478a965336239c731ebfea37ac4dde28Chris Craik} 27589561e6e4201aebc78a76ac055071ad2149db704sergeyv 27698c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, pathTextureSnapping) { 27789561e6e4201aebc78a76ac055071ad2149db704sergeyv Rect bounds(10, 15, 20, 25); 27889561e6e4201aebc78a76ac055071ad2149db704sergeyv SkPaint paint; 27989561e6e4201aebc78a76ac055071ad2149db704sergeyv SkPath path; 28089561e6e4201aebc78a76ac055071ad2149db704sergeyv path.addRect(SkRect::MakeXYWH(1.5, 3.8, 100, 90)); 28189561e6e4201aebc78a76ac055071ad2149db704sergeyv PathOp op(bounds, Matrix4::identity(), nullptr, &paint, &path); 28289561e6e4201aebc78a76ac055071ad2149db704sergeyv testUnmergedGlopDispatch(renderThread, &op, [] (const Glop& glop) { 28389561e6e4201aebc78a76ac055071ad2149db704sergeyv auto texture = glop.fill.texture.texture; 28489561e6e4201aebc78a76ac055071ad2149db704sergeyv ASSERT_NE(nullptr, texture); 28589561e6e4201aebc78a76ac055071ad2149db704sergeyv EXPECT_EQ(1, reinterpret_cast<PathTexture*>(texture)->left); 28689561e6e4201aebc78a76ac055071ad2149db704sergeyv EXPECT_EQ(3, reinterpret_cast<PathTexture*>(texture)->top); 28789561e6e4201aebc78a76ac055071ad2149db704sergeyv }); 288260ab726486317496bc12a57d599ea96dcde3284Mike Reed} 289