1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/* 2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project 3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License. 6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at 7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * http://www.apache.org/licenses/LICENSE-2.0 9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software 11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and 14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License. 15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <gtest/gtest.h> 18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 19aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik#include <DeferredLayerUpdater.h> 20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <RecordedOp.h> 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <RecordingCanvas.h> 22dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Paint.h> 23dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <minikin/Layout.h> 248160f20b0aca8c6595d4b385d673f59b6bcd16a4Chris Craik#include <tests/common/TestUtils.h> 251713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik#include <utils/Color.h> 26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 27734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik#include <SkGradientShader.h> 28734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik#include <SkShader.h> 29734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik 30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android { 31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer { 32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 33b36af87f8275f4b982906f88193ec27600f2746aChris Craikstatic void playbackOps(const DisplayList& displayList, 346fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik std::function<void(const RecordedOp&)> opReceiver) { 35161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik for (auto& chunk : displayList.getChunks()) { 36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { 37b36af87f8275f4b982906f88193ec27600f2746aChris Craik RecordedOp* op = displayList.getOps()[opIndex]; 386fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik opReceiver(*op); 39b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 40b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 41b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 42b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 43aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craikstatic void validateSingleOp(std::unique_ptr<DisplayList>& dl, 44aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik std::function<void(const RecordedOp& op)> opValidator) { 45aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 46aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik opValidator(*(dl->getOps()[0])); 47aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik} 48aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik 49b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris CraikTEST(RecordingCanvas, emptyPlayback) { 50b36af87f8275f4b982906f88193ec27600f2746aChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 51eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.restore(); 53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik }); 54818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik playbackOps(*dl, [](const RecordedOp& op) { ADD_FAILURE(); }); 55b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 56b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 57e4db79de127cfe961195f52907af8451026eaa20Chris CraikTEST(RecordingCanvas, clipRect) { 58e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) { 59eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 60e4db79de127cfe961195f52907af8451026eaa20Chris Craik canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op); 61e4db79de127cfe961195f52907af8451026eaa20Chris Craik canvas.drawRect(0, 0, 50, 50, SkPaint()); 62e4db79de127cfe961195f52907af8451026eaa20Chris Craik canvas.drawRect(50, 50, 100, 100, SkPaint()); 63e4db79de127cfe961195f52907af8451026eaa20Chris Craik canvas.restore(); 64e4db79de127cfe961195f52907af8451026eaa20Chris Craik }); 65e4db79de127cfe961195f52907af8451026eaa20Chris Craik 66e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(2u, dl->getOps().size()) << "Must be exactly two ops"; 67e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_CLIP_RECT(Rect(100, 100), dl->getOps()[0]->localClip); 68e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_CLIP_RECT(Rect(100, 100), dl->getOps()[1]->localClip); 69e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(dl->getOps()[0]->localClip, dl->getOps()[1]->localClip) 70e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Clip should be serialized once"; 71e4db79de127cfe961195f52907af8451026eaa20Chris Craik} 72e4db79de127cfe961195f52907af8451026eaa20Chris Craik 73261725fdb2962271c222a049fcdf57bbdc8363c7Chris CraikTEST(RecordingCanvas, emptyClipRect) { 74261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 75261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik canvas.save(SaveFlags::MatrixClip); 76261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op); 77261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik canvas.clipRect(100, 100, 200, 200, SkRegion::kIntersect_Op); 78261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik canvas.drawRect(0, 0, 50, 50, SkPaint()); // rejected at record time 79261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik canvas.restore(); 80261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik }); 81261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik ASSERT_EQ(0u, dl->getOps().size()) << "Must be zero ops. Rect should be rejected."; 82261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik} 83261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik 84caa24184735a607e87077c73262a42acdea7b8fbChris CraikTEST(RecordingCanvas, drawArc) { 85caa24184735a607e87077c73262a42acdea7b8fbChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 86caa24184735a607e87077c73262a42acdea7b8fbChris Craik canvas.drawArc(0, 0, 200, 200, 0, 180, true, SkPaint()); 87caa24184735a607e87077c73262a42acdea7b8fbChris Craik canvas.drawArc(0, 0, 100, 100, 0, 360, true, SkPaint()); 88caa24184735a607e87077c73262a42acdea7b8fbChris Craik }); 89caa24184735a607e87077c73262a42acdea7b8fbChris Craik 90caa24184735a607e87077c73262a42acdea7b8fbChris Craik auto&& ops = dl->getOps(); 91caa24184735a607e87077c73262a42acdea7b8fbChris Craik ASSERT_EQ(2u, ops.size()) << "Must be exactly two ops"; 92caa24184735a607e87077c73262a42acdea7b8fbChris Craik EXPECT_EQ(RecordedOpId::ArcOp, ops[0]->opId); 93caa24184735a607e87077c73262a42acdea7b8fbChris Craik EXPECT_EQ(Rect(200, 200), ops[0]->unmappedBounds); 94caa24184735a607e87077c73262a42acdea7b8fbChris Craik 95caa24184735a607e87077c73262a42acdea7b8fbChris Craik EXPECT_EQ(RecordedOpId::OvalOp, ops[1]->opId) 96caa24184735a607e87077c73262a42acdea7b8fbChris Craik << "Circular arcs should be converted to ovals"; 97caa24184735a607e87077c73262a42acdea7b8fbChris Craik EXPECT_EQ(Rect(100, 100), ops[1]->unmappedBounds); 98caa24184735a607e87077c73262a42acdea7b8fbChris Craik} 99caa24184735a607e87077c73262a42acdea7b8fbChris Craik 100a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, drawLines) { 101a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 102a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik SkPaint paint; 103386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik paint.setStrokeWidth(20); // doesn't affect recorded bounds - would be resolved at bake time 104a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik float points[] = { 0, 0, 20, 10, 30, 40, 90 }; // NB: only 1 valid line 105a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik canvas.drawLines(&points[0], 7, paint); 106a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik }); 107a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 108a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 109a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto op = dl->getOps()[0]; 110a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(RecordedOpId::LinesOp, op->opId); 111a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(4, ((LinesOp*)op)->floatCount) 112a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik << "float count must be rounded down to closest multiple of 4"; 1135430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(20, 10), op->unmappedBounds) 114386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik << "unmapped bounds must be size of line, and not outset for stroke width"; 115a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik} 116a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 117a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, drawRect) { 118b36af87f8275f4b982906f88193ec27600f2746aChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 119b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.drawRect(10, 20, 90, 180, SkPaint()); 120b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik }); 121b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 122a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 123a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto op = *(dl->getOps()[0]); 124a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(RecordedOpId::RectOp, op.opId); 125e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, op.localClip); 126a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(Rect(10, 20, 90, 180), op.unmappedBounds); 127a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik} 128a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 1292dbb4c46ee648c64bb977b6839374d73b5a605d9Chris CraikTEST(RecordingCanvas, drawRoundRect) { 1302dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik // Round case - stays rounded 1312dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 1322dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik canvas.drawRoundRect(0, 0, 100, 100, 10, 10, SkPaint()); 1332dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik }); 1342dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 1352dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik ASSERT_EQ(RecordedOpId::RoundRectOp, dl->getOps()[0]->opId); 1362dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik 1372dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik // Non-rounded case - turned into drawRect 1382dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 1392dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik canvas.drawRoundRect(0, 0, 100, 100, 0, -1, SkPaint()); 1402dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik }); 1412dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 1422dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik ASSERT_EQ(RecordedOpId::RectOp, dl->getOps()[0]->opId) 1432dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik << "Non-rounded rects should be converted"; 1442dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik} 1452dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik 146dccca44ffda4836b56a21da95a046c9708ffd49csergeyvTEST(RecordingCanvas, drawGlyphs) { 147a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 148a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik SkPaint paint; 149a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setAntiAlias(true); 150a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextSize(20); 15142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 152dccca44ffda4836b56a21da95a046c9708ffd49csergeyv TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); 153a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik }); 154a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 155b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int count = 0; 156b36af87f8275f4b982906f88193ec27600f2746aChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 157b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik count++; 158a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(RecordedOpId::TextOp, op.opId); 159e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, op.localClip); 160a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_TRUE(op.localMatrix.isIdentity()); 161a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_TRUE(op.unmappedBounds.contains(25, 15, 50, 25)) 162a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik << "Op expected to be 25+ pixels wide, 10+ pixels tall"; 163b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik }); 164a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik ASSERT_EQ(1, count); 165b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 166b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 167dccca44ffda4836b56a21da95a046c9708ffd49csergeyvTEST(RecordingCanvas, drawGlyphs_strikeThruAndUnderline) { 168a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 169a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik SkPaint paint; 170a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setAntiAlias(true); 171a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextSize(20); 17242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 173a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik for (int i = 0; i < 2; i++) { 174a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik for (int j = 0; j < 2; j++) { 175a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setUnderlineText(i != 0); 176a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setStrikeThruText(j != 0); 177dccca44ffda4836b56a21da95a046c9708ffd49csergeyv TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); 178a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik } 179a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik } 180a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik }); 181a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 182a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto ops = dl->getOps(); 183a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(8u, ops.size()); 184a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 185a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik int index = 0; 186a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId); // no underline or strikethrough 187a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 188a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId); 189a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // strikethrough only 190a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 191a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId); 192a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // underline only 193a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 194a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId); 195a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // underline 196a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // strikethrough 197a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik} 198a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 199dccca44ffda4836b56a21da95a046c9708ffd49csergeyvTEST(RecordingCanvas, drawGlyphs_forceAlignLeft) { 200a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 201a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik SkPaint paint; 202a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setAntiAlias(true); 203a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextSize(20); 20442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 205a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextAlign(SkPaint::kLeft_Align); 206dccca44ffda4836b56a21da95a046c9708ffd49csergeyv TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); 207a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextAlign(SkPaint::kCenter_Align); 208dccca44ffda4836b56a21da95a046c9708ffd49csergeyv TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); 209a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik paint.setTextAlign(SkPaint::kRight_Align); 210dccca44ffda4836b56a21da95a046c9708ffd49csergeyv TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25); 211a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik }); 212a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 213a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik int count = 0; 21442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik float lastX = FLT_MAX; 21542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik playbackOps(*dl, [&count, &lastX](const RecordedOp& op) { 216a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik count++; 217a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(RecordedOpId::TextOp, op.opId); 218a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik EXPECT_EQ(SkPaint::kLeft_Align, op.paint->getTextAlign()) 219a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik << "recorded drawText commands must force kLeft_Align on their paint"; 22042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 22142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik // verify TestUtils alignment offsetting (TODO: move asserts to Canvas base class) 22242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik EXPECT_GT(lastX, ((const TextOp&)op).x) 22342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik << "x coordinate should reduce across each of the draw commands, from alignment"; 22442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik lastX = ((const TextOp&)op).x; 225a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik }); 226a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik ASSERT_EQ(3, count); 227a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik} 228a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 2291713c7773cea83a9c1ba7e08c73434df33ca6f4bChris CraikTEST(RecordingCanvas, drawColor) { 2301713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 2311713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik canvas.drawColor(Color::Black, SkXfermode::kSrcOver_Mode); 2321713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik }); 2331713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik 2341713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op"; 2351713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik auto op = *(dl->getOps()[0]); 236a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik EXPECT_EQ(RecordedOpId::ColorOp, op.opId); 2371713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik EXPECT_EQ(nullptr, op.localClip); 238a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik EXPECT_TRUE(op.unmappedBounds.isEmpty()) << "Expect undefined recorded bounds"; 2391713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik} 2401713c7773cea83a9c1ba7e08c73434df33ca6f4bChris Craik 241b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris CraikTEST(RecordingCanvas, backgroundAndImage) { 242b36af87f8275f4b982906f88193ec27600f2746aChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) { 243b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkBitmap bitmap; 244b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bitmap.setInfo(SkImageInfo::MakeUnknown(25, 25)); 245b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkPaint paint; 246b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik paint.setColor(SK_ColorBLUE); 247b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 248eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 249b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik { 250b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // a background! 251eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 252b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.drawRect(0, 0, 100, 200, paint); 253b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.restore(); 254b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 255b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik { 256b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // an image! 257eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 258b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.translate(25, 25); 259b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.scale(2, 2); 260b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.drawBitmap(bitmap, 0, 0, nullptr); 261b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.restore(); 262b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 263b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik canvas.restore(); 264b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik }); 265b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 266b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int count = 0; 267b36af87f8275f4b982906f88193ec27600f2746aChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 268b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (count == 0) { 269b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ASSERT_EQ(RecordedOpId::RectOp, op.opId); 270b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ASSERT_NE(nullptr, op.paint); 271b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik EXPECT_EQ(SK_ColorBLUE, op.paint->getColor()); 2725430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(100, 200), op.unmappedBounds); 273e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, op.localClip); 274b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 275b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Matrix4 expectedMatrix; 276b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik expectedMatrix.loadIdentity(); 277b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); 278b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 279b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ASSERT_EQ(RecordedOpId::BitmapOp, op.opId); 280b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik EXPECT_EQ(nullptr, op.paint); 2815430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(25, 25), op.unmappedBounds); 282e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, op.localClip); 283b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 284b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Matrix4 expectedMatrix; 285b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik expectedMatrix.loadTranslate(25, 25, 0); 286b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik expectedMatrix.scale(2, 2, 1); 287b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); 288b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 289b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik count++; 290b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik }); 291a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik ASSERT_EQ(2, count); 292b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 293b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 294aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris CraikRENDERTHREAD_TEST(RecordingCanvas, textureLayer) { 295aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100, 296aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik SkMatrix::MakeTrans(5, 5)); 297aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik 298aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, 299aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik [&layerUpdater](RecordingCanvas& canvas) { 300aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik canvas.drawLayer(layerUpdater.get()); 301aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik }); 302aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik 303aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik validateSingleOp(dl, [] (const RecordedOp& op) { 304aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik ASSERT_EQ(RecordedOpId::TextureLayerOp, op.opId); 305aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik ASSERT_TRUE(op.localMatrix.isIdentity()) << "Op must not apply matrix at record time."; 306aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik }); 307aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik} 308aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik 309a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, saveLayer_simple) { 3106fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 311eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(10, 20, 190, 180, 128, SaveFlags::ClipToLayer); 3126fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.drawRect(10, 20, 190, 180, SkPaint()); 3136fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 3146fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 3156fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int count = 0; 3166fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 3176fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Matrix4 expectedMatrix; 3186fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik switch(count++) { 3196fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik case 0: 3206fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::BeginLayerOp, op.opId); 321a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds); 322e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, op.localClip); 323a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik EXPECT_TRUE(op.localMatrix.isIdentity()); 3246fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik break; 3256fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik case 1: 3266fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::RectOp, op.opId); 327e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_CLIP_RECT(Rect(180, 160), op.localClip); 3286fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds); 3296fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik expectedMatrix.loadTranslate(-10, -20, 0); 3306fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); 3316fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik break; 3326fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik case 2: 3336fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::EndLayerOp, op.opId); 334a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik // Don't bother asserting recording state data - it's not used 3356fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik break; 3366fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik default: 337818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik ADD_FAILURE(); 3386fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 3396fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 3406fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(3, count); 341b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 3426fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 343b87eadda1818034ce03d85f30388384d1ac65916Chris CraikTEST(RecordingCanvas, saveLayer_missingRestore) { 344b87eadda1818034ce03d85f30388384d1ac65916Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 345eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer); 346b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.drawRect(0, 0, 200, 200, SkPaint()); 347b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // Note: restore omitted, shouldn't result in unmatched save 348b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 349b87eadda1818034ce03d85f30388384d1ac65916Chris Craik int count = 0; 350b87eadda1818034ce03d85f30388384d1ac65916Chris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 351b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (count++ == 2) { 352b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(RecordedOpId::EndLayerOp, op.opId); 353b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 354b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 355b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(3, count) << "Missing a restore shouldn't result in an unmatched saveLayer"; 356b87eadda1818034ce03d85f30388384d1ac65916Chris Craik} 357b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 358b87eadda1818034ce03d85f30388384d1ac65916Chris CraikTEST(RecordingCanvas, saveLayer_simpleUnclipped) { 359b87eadda1818034ce03d85f30388384d1ac65916Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 360eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0); // unclipped 361b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.drawRect(10, 20, 190, 180, SkPaint()); 362b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.restore(); 363b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 364b87eadda1818034ce03d85f30388384d1ac65916Chris Craik int count = 0; 365b87eadda1818034ce03d85f30388384d1ac65916Chris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 366b87eadda1818034ce03d85f30388384d1ac65916Chris Craik switch(count++) { 367b87eadda1818034ce03d85f30388384d1ac65916Chris Craik case 0: 368b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(RecordedOpId::BeginUnclippedLayerOp, op.opId); 369b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds); 370b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(nullptr, op.localClip); 371b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_TRUE(op.localMatrix.isIdentity()); 372b87eadda1818034ce03d85f30388384d1ac65916Chris Craik break; 373b87eadda1818034ce03d85f30388384d1ac65916Chris Craik case 1: 374b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(RecordedOpId::RectOp, op.opId); 375b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(nullptr, op.localClip); 376b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds); 377b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_TRUE(op.localMatrix.isIdentity()); 378b87eadda1818034ce03d85f30388384d1ac65916Chris Craik break; 379b87eadda1818034ce03d85f30388384d1ac65916Chris Craik case 2: 380b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(RecordedOpId::EndUnclippedLayerOp, op.opId); 381b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // Don't bother asserting recording state data - it's not used 382b87eadda1818034ce03d85f30388384d1ac65916Chris Craik break; 383b87eadda1818034ce03d85f30388384d1ac65916Chris Craik default: 384b87eadda1818034ce03d85f30388384d1ac65916Chris Craik ADD_FAILURE(); 385b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 386b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 387b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(3, count); 388b87eadda1818034ce03d85f30388384d1ac65916Chris Craik} 389b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 390b87eadda1818034ce03d85f30388384d1ac65916Chris CraikTEST(RecordingCanvas, saveLayer_addClipFlag) { 391b87eadda1818034ce03d85f30388384d1ac65916Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 392eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 393b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.clipRect(10, 20, 190, 180, SkRegion::kIntersect_Op); 394eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0); // unclipped 395b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.drawRect(10, 20, 190, 180, SkPaint()); 396b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.restore(); 397b87eadda1818034ce03d85f30388384d1ac65916Chris Craik canvas.restore(); 398b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 399b87eadda1818034ce03d85f30388384d1ac65916Chris Craik int count = 0; 400b87eadda1818034ce03d85f30388384d1ac65916Chris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 401b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (count++ == 0) { 402b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(RecordedOpId::BeginLayerOp, op.opId) 403b87eadda1818034ce03d85f30388384d1ac65916Chris Craik << "Clip + unclipped saveLayer should result in a clipped layer"; 404b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 405b87eadda1818034ce03d85f30388384d1ac65916Chris Craik }); 406b87eadda1818034ce03d85f30388384d1ac65916Chris Craik EXPECT_EQ(3, count); 407b87eadda1818034ce03d85f30388384d1ac65916Chris Craik} 408b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 409a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, saveLayer_viewportCrop) { 4106fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 4116fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // shouldn't matter, since saveLayer will clip to its bounds 4126fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.clipRect(-1000, -1000, 1000, 1000, SkRegion::kReplace_Op); 4136fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 414eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer); 4156fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 4166fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 4176fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4186fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int count = 0; 4196fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 4206fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (count++ == 1) { 4216fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Matrix4 expectedMatrix; 4226fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::RectOp, op.opId); 423e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_CLIP_RECT(Rect(100, 100), op.localClip) // Recorded clip rect should be 424e4db79de127cfe961195f52907af8451026eaa20Chris Craik // intersection of viewport and saveLayer bounds, in layer space; 4255430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(400, 400), op.unmappedBounds); 4266fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik expectedMatrix.loadTranslate(-100, -100, 0); 4276fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); 4286fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 4296fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4306fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(3, count); 431b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 4326fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 433a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, saveLayer_rotateUnclipped) { 4346fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 435eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 4366fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.translate(100, 100); 4376fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.rotate(45); 4386fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.translate(-50, -50); 4396fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 440eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(0, 0, 100, 100, 128, SaveFlags::ClipToLayer); 4416fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.drawRect(0, 0, 100, 100, SkPaint()); 4426fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 4436fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 4446fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 4456fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4466fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int count = 0; 4476fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 4486fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (count++ == 1) { 4496fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::RectOp, op.opId); 450e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_CLIP_RECT(Rect(100, 100), op.localClip); 4515430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(100, 100), op.unmappedBounds); 452a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), op.localMatrix) 453a6ac95e5772c5df441b49189af3a0df79a22679dChris Craik << "Recorded op shouldn't see any canvas transform before the saveLayer"; 4546fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 4556fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4566fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(3, count); 4576fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 4586fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 459a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, saveLayer_rotateClipped) { 4606fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 461eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.save(SaveFlags::MatrixClip); 4626fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.translate(100, 100); 4636fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.rotate(45); 4646fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.translate(-200, -200); 4656fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 4666fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // area of saveLayer will be clipped to parent viewport, so we ask for 400x400... 467eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita canvas.saveLayerAlpha(0, 0, 400, 400, 128, SaveFlags::ClipToLayer); 4686fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 4696fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 4706fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 4716fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik canvas.restore(); 4726fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4736fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int count = 0; 4746fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik playbackOps(*dl, [&count](const RecordedOp& op) { 4756fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (count++ == 1) { 4766fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Matrix4 expectedMatrix; 4776fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(RecordedOpId::RectOp, op.opId); 4786fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 4796fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // ...and get about 58.6, 58.6, 341.4 341.4, because the bounds are clipped by 4806fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // the parent 200x200 viewport, but prior to rotation 481e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, op.localClip); 482e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::Rectangle, op.localClip->mode); 483e4db79de127cfe961195f52907af8451026eaa20Chris Craik // NOTE: this check relies on saveLayer altering the clip post-viewport init. This 484e4db79de127cfe961195f52907af8451026eaa20Chris Craik // causes the clip to be recorded by contained draw commands, though it's not necessary 485e4db79de127cfe961195f52907af8451026eaa20Chris Craik // since the same clip will be computed at draw time. If such a change is made, this 486e4db79de127cfe961195f52907af8451026eaa20Chris Craik // check could be done at record time by querying the clip, or the clip could be altered 487e4db79de127cfe961195f52907af8451026eaa20Chris Craik // slightly so that it is serialized. 48869aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik EXPECT_EQ(Rect(59, 59, 341, 341), op.localClip->rect); 4895430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik EXPECT_EQ(Rect(400, 400), op.unmappedBounds); 4906fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik expectedMatrix.loadIdentity(); 4916fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); 4926fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 4936fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik }); 4946fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik EXPECT_EQ(3, count); 4956fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 4966fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 4971367d2550ebce40f45b16dc651bc3d8d22930801Chris CraikTEST(RecordingCanvas, drawRenderNode_rejection) { 4981367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik auto child = TestUtils::createNode(50, 50, 150, 150, 4991367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik [](RenderProperties& props, RecordingCanvas& canvas) { 5001367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik SkPaint paint; 5011367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik paint.setColor(SK_ColorWHITE); 5021367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik canvas.drawRect(0, 0, 100, 100, paint); 5031367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik }); 5041367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik 5051367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&child](RecordingCanvas& canvas) { 5061367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik canvas.clipRect(0, 0, 0, 0, SkRegion::kIntersect_Op); // empty clip, reject node 5071367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik canvas.drawRenderNode(child.get()); // shouldn't crash when rejecting node... 5081367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik }); 5091367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik ASSERT_TRUE(dl->isEmpty()); 5101367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik} 5111367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik 5128d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris CraikTEST(RecordingCanvas, drawRenderNode_projection) { 5138d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik sp<RenderNode> background = TestUtils::createNode(50, 50, 150, 150, 5148d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik [](RenderProperties& props, RecordingCanvas& canvas) { 5158d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik SkPaint paint; 5168d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik paint.setColor(SK_ColorWHITE); 5178d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRect(0, 0, 100, 100, paint); 5188d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik }); 5198d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik { 5208d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik background->mutateStagingProperties().setProjectionReceiver(false); 5218d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 5228d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik // NO RECEIVER PRESENT 5238d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, 5248d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik [&background](RecordingCanvas& canvas) { 5258d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRect(0, 0, 100, 100, SkPaint()); 5268d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRenderNode(background.get()); 5278d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRect(0, 0, 100, 100, SkPaint()); 5288d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik }); 5298d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik EXPECT_EQ(-1, dl->projectionReceiveIndex) 5308d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik << "no projection receiver should have been observed"; 5318d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik } 5328d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik { 5338d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik background->mutateStagingProperties().setProjectionReceiver(true); 5348d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 5358d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik // RECEIVER PRESENT 5368d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, 5378d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik [&background](RecordingCanvas& canvas) { 5388d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRect(0, 0, 100, 100, SkPaint()); 5398d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRenderNode(background.get()); 5408d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik canvas.drawRect(0, 0, 100, 100, SkPaint()); 5418d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik }); 5428d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 5438d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik ASSERT_EQ(3u, dl->getOps().size()) << "Must be three ops"; 5448d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik auto op = dl->getOps()[1]; 5458d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik EXPECT_EQ(RecordedOpId::RenderNodeOp, op->opId); 5468d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik EXPECT_EQ(1, dl->projectionReceiveIndex) 5478d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik << "correct projection receiver not identified"; 5488d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 5498d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik // verify the behavior works even though projection receiver hasn't been sync'd yet 5508d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik EXPECT_TRUE(background->stagingProperties().isProjectionReceiver()); 5518d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik EXPECT_FALSE(background->properties().isProjectionReceiver()); 5528d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik } 5538d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik} 5548d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 5557fc1b0349bc2ac8c880120dc5611f703faa7f06fChris CraikTEST(RecordingCanvas, firstClipWillReplace) { 5567fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 5577fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik canvas.save(SaveFlags::MatrixClip); 5587fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik // since no explicit clip set on canvas, this should be the one observed on op: 5597fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik canvas.clipRect(-100, -100, 300, 300, SkRegion::kIntersect_Op); 5607fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik 5617fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik SkPaint paint; 5627fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik paint.setColor(SK_ColorWHITE); 5637fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik canvas.drawRect(0, 0, 100, 100, paint); 5647fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik 5657fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik canvas.restore(); 5667fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik }); 5677fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op"; 5687fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik // first clip must be preserved, even if it extends beyond canvas bounds 5697fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik EXPECT_CLIP_RECT(Rect(-100, -100, 300, 300), dl->getOps()[0]->localClip); 5707fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik} 5717fc1b0349bc2ac8c880120dc5611f703faa7f06fChris Craik 57204d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris CraikTEST(RecordingCanvas, replaceClipIntersectWithRoot) { 57304d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) { 57404d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik canvas.save(SaveFlags::MatrixClip); 57504d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik canvas.clipRect(-10, -10, 110, 110, SkRegion::kReplace_Op); 57604d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode); 57704d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik canvas.restore(); 57804d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik }); 57904d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op"; 58004d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik // first clip must be preserved, even if it extends beyond canvas bounds 58104d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik EXPECT_CLIP_RECT(Rect(-10, -10, 110, 110), dl->getOps()[0]->localClip); 58204d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik EXPECT_TRUE(dl->getOps()[0]->localClip->intersectWithRoot); 58304d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik} 58404d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik 585a1717271caac5e8ea3808c331d4141ac01a42134Chris CraikTEST(RecordingCanvas, insertReorderBarrier) { 586161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 587161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 588161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.insertReorderBarrier(true); 589161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.insertReorderBarrier(false); 590161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.insertReorderBarrier(false); 591161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.insertReorderBarrier(true); 592161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 593161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik canvas.insertReorderBarrier(false); 594161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik }); 595161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik 596161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik auto chunks = dl->getChunks(); 597161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_EQ(0u, chunks[0].beginOpIndex); 598161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_EQ(1u, chunks[0].endOpIndex); 599161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_FALSE(chunks[0].reorderChildren); 600161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik 601161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_EQ(1u, chunks[1].beginOpIndex); 602161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_EQ(2u, chunks[1].endOpIndex); 603161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik EXPECT_TRUE(chunks[1].reorderChildren); 604161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik} 605161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik 606d645640180c25c2711e99aa82ec629155f8e91baChris CraikTEST(RecordingCanvas, insertReorderBarrier_clip) { 607d645640180c25c2711e99aa82ec629155f8e91baChris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 608d645640180c25c2711e99aa82ec629155f8e91baChris Craik // first chunk: no recorded clip 609d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.insertReorderBarrier(true); 610d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 611d645640180c25c2711e99aa82ec629155f8e91baChris Craik 612d645640180c25c2711e99aa82ec629155f8e91baChris Craik // second chunk: no recorded clip, since inorder region 613d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op); 614d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.insertReorderBarrier(false); 615d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 616d645640180c25c2711e99aa82ec629155f8e91baChris Craik 617d645640180c25c2711e99aa82ec629155f8e91baChris Craik // third chunk: recorded clip 618d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.insertReorderBarrier(true); 619d645640180c25c2711e99aa82ec629155f8e91baChris Craik canvas.drawRect(0, 0, 400, 400, SkPaint()); 620d645640180c25c2711e99aa82ec629155f8e91baChris Craik }); 621d645640180c25c2711e99aa82ec629155f8e91baChris Craik 622d645640180c25c2711e99aa82ec629155f8e91baChris Craik auto chunks = dl->getChunks(); 623d645640180c25c2711e99aa82ec629155f8e91baChris Craik ASSERT_EQ(3u, chunks.size()); 624d645640180c25c2711e99aa82ec629155f8e91baChris Craik 625d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_TRUE(chunks[0].reorderChildren); 626d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_EQ(nullptr, chunks[0].reorderClip); 627d645640180c25c2711e99aa82ec629155f8e91baChris Craik 628d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_FALSE(chunks[1].reorderChildren); 629d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_EQ(nullptr, chunks[1].reorderClip); 630d645640180c25c2711e99aa82ec629155f8e91baChris Craik 631d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_TRUE(chunks[2].reorderChildren); 632d645640180c25c2711e99aa82ec629155f8e91baChris Craik ASSERT_NE(nullptr, chunks[2].reorderClip); 633d645640180c25c2711e99aa82ec629155f8e91baChris Craik EXPECT_EQ(Rect(200, 200), chunks[2].reorderClip->rect); 634d645640180c25c2711e99aa82ec629155f8e91baChris Craik} 635d645640180c25c2711e99aa82ec629155f8e91baChris Craik 63642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris CraikTEST(RecordingCanvas, refPaint) { 63742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik SkPaint paint; 63842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 63942a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&paint](RecordingCanvas& canvas) { 64042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik paint.setColor(SK_ColorBLUE); 64179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger // first two should use same paint 64242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik canvas.drawRect(0, 0, 200, 10, paint); 64342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik SkPaint paintCopy(paint); 64442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik canvas.drawRect(0, 10, 200, 20, paintCopy); 64542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 64642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik // only here do we use different paint ptr 64742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik paint.setColor(SK_ColorRED); 64842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik canvas.drawRect(0, 20, 200, 30, paint); 64942a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik }); 65042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik auto ops = dl->getOps(); 65179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger ASSERT_EQ(3u, ops.size()); 65242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 65379abbf22d4f672208327546661e694d837f564a9Derek Sollenberger // first two are the same 65442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik EXPECT_NE(nullptr, ops[0]->paint); 65542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik EXPECT_NE(&paint, ops[0]->paint); 65642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik EXPECT_EQ(ops[0]->paint, ops[1]->paint); 65742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 65842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik // last is different, but still copied / non-null 65979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger EXPECT_NE(nullptr, ops[2]->paint); 66079abbf22d4f672208327546661e694d837f564a9Derek Sollenberger EXPECT_NE(ops[0]->paint, ops[2]->paint); 66179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger EXPECT_NE(&paint, ops[2]->paint); 66242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik} 66342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik 664bee6092dbef81ff724624c4dd630efa8657817f8Chris CraikTEST(RecordingCanvas, refBitmap) { 665bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik SkBitmap bitmap = TestUtils::createSkBitmap(100, 100); 666bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) { 667bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik canvas.drawBitmap(bitmap, 0, 0, nullptr); 668bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik }); 669bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik auto& bitmaps = dl->getBitmapResources(); 670bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik EXPECT_EQ(1u, bitmaps.size()); 671bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik} 672bee6092dbef81ff724624c4dd630efa8657817f8Chris Craik 673734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris CraikTEST(RecordingCanvas, refBitmapInShader_bitmapShader) { 674734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkBitmap bitmap = TestUtils::createSkBitmap(100, 100); 675734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) { 676734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkPaint paint; 677734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(bitmap, 678734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkShader::TileMode::kClamp_TileMode, 679734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkShader::TileMode::kClamp_TileMode)); 680734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik paint.setShader(shader); 681734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint); 682734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik }); 683734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik auto& bitmaps = dl->getBitmapResources(); 684734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik EXPECT_EQ(1u, bitmaps.size()); 685734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik} 686734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik 687734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris CraikTEST(RecordingCanvas, refBitmapInShader_composeShader) { 688734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkBitmap bitmap = TestUtils::createSkBitmap(100, 100); 689734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) { 690734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkPaint paint; 691734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkAutoTUnref<SkShader> shader1(SkShader::CreateBitmapShader(bitmap, 692734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkShader::TileMode::kClamp_TileMode, 693734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkShader::TileMode::kClamp_TileMode)); 694734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik 695734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkPoint center; 696734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik center.set(50, 50); 697734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkColor colors[2]; 698734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik colors[0] = Color::Black; 699734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik colors[1] = Color::White; 700734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkAutoTUnref<SkShader> shader2(SkGradientShader::CreateRadial(center, 50, colors, nullptr, 2, 701734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkShader::TileMode::kRepeat_TileMode)); 702734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik 703734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkAutoTUnref<SkShader> composeShader(SkShader::CreateComposeShader(shader1, shader2, 704734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik SkXfermode::Mode::kMultiply_Mode)); 705734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik paint.setShader(composeShader); 706734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint); 707734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik }); 708734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik auto& bitmaps = dl->getBitmapResources(); 709734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik EXPECT_EQ(1u, bitmaps.size()); 710734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik} 711734f146c1ebf43816d5a3c8e82c726ab09489cb9Chris Craik 712dccca44ffda4836b56a21da95a046c9708ffd49csergeyvTEST(RecordingCanvas, drawText) { 713dccca44ffda4836b56a21da95a046c9708ffd49csergeyv auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 714dccca44ffda4836b56a21da95a046c9708ffd49csergeyv Paint paint; 715dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setAntiAlias(true); 716dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setTextSize(20); 717dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 71879abbf22d4f672208327546661e694d837f564a9Derek Sollenberger std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO"); 719dccca44ffda4836b56a21da95a046c9708ffd49csergeyv canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL); 720dccca44ffda4836b56a21da95a046c9708ffd49csergeyv }); 721dccca44ffda4836b56a21da95a046c9708ffd49csergeyv 722dccca44ffda4836b56a21da95a046c9708ffd49csergeyv int count = 0; 723dccca44ffda4836b56a21da95a046c9708ffd49csergeyv playbackOps(*dl, [&count](const RecordedOp& op) { 724dccca44ffda4836b56a21da95a046c9708ffd49csergeyv count++; 725dccca44ffda4836b56a21da95a046c9708ffd49csergeyv ASSERT_EQ(RecordedOpId::TextOp, op.opId); 726dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_EQ(nullptr, op.localClip); 727dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_TRUE(op.localMatrix.isIdentity()); 728dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_TRUE(op.unmappedBounds.getHeight() >= 10); 729dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_TRUE(op.unmappedBounds.getWidth() >= 25); 730dccca44ffda4836b56a21da95a046c9708ffd49csergeyv }); 731dccca44ffda4836b56a21da95a046c9708ffd49csergeyv ASSERT_EQ(1, count); 732dccca44ffda4836b56a21da95a046c9708ffd49csergeyv} 733dccca44ffda4836b56a21da95a046c9708ffd49csergeyv 734dccca44ffda4836b56a21da95a046c9708ffd49csergeyvTEST(RecordingCanvas, drawTextInHighContrast) { 735dccca44ffda4836b56a21da95a046c9708ffd49csergeyv auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) { 736dccca44ffda4836b56a21da95a046c9708ffd49csergeyv canvas.setHighContrastText(true); 737dccca44ffda4836b56a21da95a046c9708ffd49csergeyv Paint paint; 738dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setColor(SK_ColorWHITE); 739dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setAntiAlias(true); 740dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setTextSize(20); 741dccca44ffda4836b56a21da95a046c9708ffd49csergeyv paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 74279abbf22d4f672208327546661e694d837f564a9Derek Sollenberger std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO"); 743dccca44ffda4836b56a21da95a046c9708ffd49csergeyv canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL); 744dccca44ffda4836b56a21da95a046c9708ffd49csergeyv }); 745dccca44ffda4836b56a21da95a046c9708ffd49csergeyv 746dccca44ffda4836b56a21da95a046c9708ffd49csergeyv int count = 0; 747dccca44ffda4836b56a21da95a046c9708ffd49csergeyv playbackOps(*dl, [&count](const RecordedOp& op) { 748dccca44ffda4836b56a21da95a046c9708ffd49csergeyv ASSERT_EQ(RecordedOpId::TextOp, op.opId); 749dccca44ffda4836b56a21da95a046c9708ffd49csergeyv if (count++ == 0) { 750dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_EQ(SK_ColorBLACK, op.paint->getColor()); 751dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_EQ(SkPaint::kStrokeAndFill_Style, op.paint->getStyle()); 752dccca44ffda4836b56a21da95a046c9708ffd49csergeyv } else { 753dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_EQ(SK_ColorWHITE, op.paint->getColor()); 754dccca44ffda4836b56a21da95a046c9708ffd49csergeyv EXPECT_EQ(SkPaint::kFill_Style, op.paint->getStyle()); 755dccca44ffda4836b56a21da95a046c9708ffd49csergeyv } 756dccca44ffda4836b56a21da95a046c9708ffd49csergeyv 757dccca44ffda4836b56a21da95a046c9708ffd49csergeyv }); 758dccca44ffda4836b56a21da95a046c9708ffd49csergeyv ASSERT_EQ(2, count); 759dccca44ffda4836b56a21da95a046c9708ffd49csergeyv} 760dccca44ffda4836b56a21da95a046c9708ffd49csergeyv 7616fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} // namespace uirenderer 7626fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} // namespace android 763