18f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org/* 28f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * Copyright 2013 Google Inc. 38f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * 48f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 58f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * found in the LICENSE file. 68f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org */ 7ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.org 88f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkBitmap.h" 91f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h" 108f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkCanvas.h" 118f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkDraw.h" 128f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkLayerDrawLooper.h" 138f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkMatrix.h" 148f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkPaint.h" 158f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkRect.h" 168f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkRefCnt.h" 178f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkScalar.h" 1879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 198f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkXfermode.h" 208f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h" 218f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 2215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgstatic SkBitmap make_bm(int w, int h) { 2315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkBitmap bm; 2415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bm.allocN32Pixels(w, h); 2515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return bm; 2615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org} 2715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 281f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comclass FakeDevice : public SkBitmapDevice { 298f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgpublic: 3015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org FakeDevice() : SkBitmapDevice(make_bm(100, 100)) { } 318f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 327f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com virtual void drawRect(const SkDraw& draw, const SkRect& r, 333e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org const SkPaint& paint) SK_OVERRIDE { 348f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org fLastMatrix = *draw.fMatrix; 3584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->INHERITED::drawRect(draw, r, paint); 368f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org } 378f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 388f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkMatrix fLastMatrix; 391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com 401f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comprivate: 411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com typedef SkBitmapDevice INHERITED; 428f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}; 438f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 448f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_frontToBack(skiatest::Reporter* reporter) { 4574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkLayerDrawLooper::Builder looperBuilder; 468f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkLayerDrawLooper::LayerInfo layerInfo; 478f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 488f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the front layer, with the defaults. 4974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org (void)looperBuilder.addLayer(layerInfo); 508f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 518f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the back layer, with some layer info set. 524b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org layerInfo.fOffset.set(10.0f, 20.0f); 538f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 5474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkPaint* layerPaint = looperBuilder.addLayer(layerInfo); 558f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 568f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 578f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org FakeDevice device; 588f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkCanvas canvas(&device); 598f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkPaint paint; 6074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper()); 6179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> allocator; 6279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize()); 6379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* context = looper->createContext(&canvas, buffer); 648f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 658f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // The back layer should come first. 6679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 678f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 684b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 694b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 704b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 718f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org paint.reset(); 728f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 738f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Then the front layer. 7479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 758f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 764b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 774b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 784b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 798f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 808f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Only two layers were added, so that should be the end. 8179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 828f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org} 838f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 848f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_backToFront(skiatest::Reporter* reporter) { 8574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkLayerDrawLooper::Builder looperBuilder; 868f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkLayerDrawLooper::LayerInfo layerInfo; 878f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 888f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the back layer, with the defaults. 8974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org (void)looperBuilder.addLayerOnTop(layerInfo); 908f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 918f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the front layer, with some layer info set. 924b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org layerInfo.fOffset.set(10.0f, 20.0f); 938f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 9474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo); 958f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 968f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 978f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org FakeDevice device; 988f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkCanvas canvas(&device); 998f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkPaint paint; 10074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper()); 10179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> allocator; 10279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize()); 10379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* context = looper->createContext(&canvas, buffer); 1048f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1058f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // The back layer should come first. 10679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 1078f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 1084b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 1094b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 1104b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 1118f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org paint.reset(); 1128f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1138f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Then the front layer. 11479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 1158f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 1164b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 1174b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 1184b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 1198f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1208f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Only two layers were added, so that should be the end. 12179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 1228f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org} 1238f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1248f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_mixed(skiatest::Reporter* reporter) { 12574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkLayerDrawLooper::Builder looperBuilder; 1268f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkLayerDrawLooper::LayerInfo layerInfo; 1278f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1288f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the back layer, with the defaults. 12974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org (void)looperBuilder.addLayer(layerInfo); 1308f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1318f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Add the front layer, with some layer info set. 1324b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org layerInfo.fOffset.set(10.0f, 20.0f); 1338f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 13474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo); 1358f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); 1368f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1378f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org FakeDevice device; 1388f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkCanvas canvas(&device); 1398f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org SkPaint paint; 14074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper()); 14179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> allocator; 14279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize()); 14379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* context = looper->createContext(&canvas, buffer); 1448f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1458f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // The back layer should come first. 14679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 1478f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); 1484b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 1494b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 1504b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 1518f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org paint.reset(); 1528f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1538f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Then the front layer. 15479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 1558f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); 1564b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 1574b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 1584b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 1598f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 1608f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org // Only two layers were added, so that should be the end. 16179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 1628f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org} 1638f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org 164e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(LayerDrawLooper, reporter) { 1658f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org test_frontToBack(reporter); 1668f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org test_backToFront(reporter); 1678f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org test_mixed(reporter); 1688f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org} 169