180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h" 100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkBitmapDevice.h" 11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkBitmapProcShader.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDeferredCanvas.h" 13096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkGradientShader.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkShader.h" 15e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger#include "../src/image/SkSurface_Base.h" 16e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger#include "../src/image/SkImagePriv.h" 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if SK_SUPPORT_GPU 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrContextFactory.h" 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrContextFactory; 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gWidth = 2; 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gHeight = 2; 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) { 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm->setConfig(config, gWidth, gHeight); 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm->allocPixels(); 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm->eraseColor(color); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) { 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 37e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(store); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred 4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkBitmap accessed = canvas->getDevice()->accessBitmap(false); 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef()); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenbergerclass MockSurface : public SkSurface_Base { 49e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenbergerpublic: 50e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger MockSurface(int width, int height) : SkSurface_Base(width, height) { 51e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger clearCounts(); 52e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); 53e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fBitmap.allocPixels(); 54e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 55e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 56e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger virtual SkCanvas* onNewCanvas() SK_OVERRIDE { 57e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return SkNEW_ARGS(SkCanvas, (fBitmap)); 58e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 59e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE { 61e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return NULL; 62e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 63e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 64e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger virtual SkImage* onNewImageSnapshot() SK_OVERRIDE { 65e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return SkNewImageFromBitmap(fBitmap, true); 66e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 67e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 68e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger virtual void onCopyOnWrite(ContentChangeMode mode) SK_OVERRIDE { 69e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (mode == SkSurface::kDiscard_ContentChangeMode) { 70e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fDiscardCount++; 71e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } else { 72e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fRetainCount++; 73e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 74e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 75e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 76e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger void clearCounts() { 77e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fDiscardCount = 0; 78e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger fRetainCount = 0; 79e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 80e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 81e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger int fDiscardCount, fRetainCount; 82e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkBitmap fBitmap; 83e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger}; 84e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 85e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenbergerstatic void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter) { 86e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<MockSurface> surface(SkNEW_ARGS(MockSurface, (10, 10))); 87e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get())); 88e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 89e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkBitmap srcBitmap; 90e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger srcBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); 91e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger srcBitmap.allocPixels(); 92e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger srcBitmap.eraseColor(SK_ColorGREEN); 93e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Tests below depend on this bitmap being recognized as opaque 94e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 95e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Preliminary sanity check: no copy on write if no active snapshot 96e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 97e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->clear(SK_ColorWHITE); 98e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 99e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 100e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 101e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 102e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 103e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 104e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 105e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 106e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 1: Discard notification happens upon flushing 107e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // with an Image attached. 108e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 109e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); 110e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 111e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 112e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 113e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 114e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->clear(SK_ColorWHITE); 115e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 116e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 117e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 118e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 119e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 120e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); 121e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 122e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 123e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 2: Opaque writePixels 124e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 125e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); 126e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 127e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 128e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 129e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 130e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 0, 0); 131e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 132e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 133e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 134e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 135e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 136e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); 137e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 138e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 139e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 3: writePixels that partially covers the canvas 140e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 141e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image3(canvas->newImageSnapshot()); 142e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 143e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 144e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 145e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 146e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 5, 0); 147e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 148e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 149e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 150e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 151e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 152e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 153e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); 154e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 155e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 4: unpremultiplied opaque writePixels that entirely 156e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas 157e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 158e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image4(canvas->newImageSnapshot()); 159e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 160e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 161e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 162e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 163e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888); 164e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); 165e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 166e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 167e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 168e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 169e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 170e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 171e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 172e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 5: unpremultiplied opaque writePixels that partially 173e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas 174e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 175e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image5(canvas->newImageSnapshot()); 176e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 177e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 178e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 179e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 180e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); 181e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 182e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); 183e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 184e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 185e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 186e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 187e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 188e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 189e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 6: unpremultiplied opaque writePixels that entirely 190e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas, preceded by clear 191e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 192e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image6(canvas->newImageSnapshot()); 193e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 194e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 195e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 196e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 197e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->clear(SK_ColorWHITE); 198e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 199e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 200e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 201e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 202e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888); 203e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); 204e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 205e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 206e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 207e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 208e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 209e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 210e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 211e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 7: unpremultiplied opaque writePixels that partially 212e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas, preceeded by a clear 213e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 214e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image7(canvas->newImageSnapshot()); 215e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 216e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 217e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 218e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 219e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->clear(SK_ColorWHITE); 220e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 221e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 222e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 223e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 224e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); 225e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); // because of the clear 226e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 227e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 228e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 229e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 230e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 231e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 232e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 233e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // Case 8: unpremultiplied opaque writePixels that partially 234e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas, preceeded by a drawREct that partially 235e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // covers the canvas 236e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 237e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkImage> image8(canvas->newImageSnapshot()); 238e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 239e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 240e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 241e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 242e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkPaint paint; 243e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->drawRect(SkRect::MakeLTRB(0, 0, 5, 5), paint); 244e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 245e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 246e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 247e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 248e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888); 249e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 250e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 1 == surface->fRetainCount); 251e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 252e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger surface->clearCounts(); 253e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger canvas->flush(); 254e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount); 255e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger REPORTER_ASSERT(reporter, 0 == surface->fRetainCount); 256e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger} 257e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasFlush(skiatest::Reporter* reporter) { 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 2620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 263e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(store); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred 26958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) { 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect fullRect; 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth), 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(gHeight)); 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect partialRect; 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(1), SkIntToScalar(1)); 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 2820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 283e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // verify that frame is intially fresh 28658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no clearing op since last call to isFreshFrame -> not fresh 28858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that clear triggers a fresh frame 29158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 29258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that clear with saved state triggers a fresh frame 29558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->save(SkCanvas::kMatrixClip_SaveFlag); 29658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 29758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restore(); 29858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that clear within a layer does NOT trigger a fresh frame 30158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->saveLayer(NULL, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); 30258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 30358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restore(); 30458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that a clear with clipping triggers a fresh frame 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // (clear is not affected by clipping) 30858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->save(SkCanvas::kMatrixClip_SaveFlag); 30958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false); 31058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x00000000); 31158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restore(); 31258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that full frame rects with different forms of opaque paint 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // trigger frames to be marked as fresh 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 318096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 319096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(255); 32058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 32158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 325096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 326096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(255); 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setXfermodeMode(SkXfermode::kSrcIn_Mode); 32858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 32958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 333096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap bmp; 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 3360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bmp.setAlphaType(kOpaque_SkAlphaType); 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = SkShader::CreateBitmapShader(bmp, 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader)->unref(); 34058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 34158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that full frame rects with different forms of non-opaque paint 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // do not trigger frames to be marked as fresh 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 348096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 349096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(254); 35058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 35158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 355096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 356096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // Defining a cone that partially overlaps the canvas 357096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkPoint pt1 = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0)); 358096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkScalar r1 = SkIntToScalar(1); 359096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkPoint pt2 = SkPoint::Make(SkIntToScalar(10), SkIntToScalar(0)); 360096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkScalar r2 = SkIntToScalar(5); 361096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkColor colors[2] = {SK_ColorWHITE, SK_ColorWHITE}; 362096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkScalar pos[2] = {0, SK_Scalar1}; 363096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkShader* shader = SkGradientShader::CreateTwoPointConical( 364096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger pt1, r1, pt2, r2, colors, pos, 2, SkShader::kClamp_TileMode, NULL); 365096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setShader(shader)->unref(); 36658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 36758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 368096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 369096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger { 370096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkPaint paint; 371096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap bmp; 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 3740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bmp.setAlphaType(kPremul_SkAlphaType); 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = SkShader::CreateBitmapShader(bmp, 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setShader(shader)->unref(); 37858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 37958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that incomplete coverage does not trigger a fresh frame 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setStyle(SkPaint::kFill_Style); 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setAlpha(255); 38758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(partialRect, paint); 38858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that incomplete coverage due to clipping does not trigger a fresh 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // frame 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 39458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->save(SkCanvas::kMatrixClip_SaveFlag); 39558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false); 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setStyle(SkPaint::kFill_Style); 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setAlpha(255); 39958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 40058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restore(); 40158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 402363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 403363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { 40458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->save(SkCanvas::kMatrixClip_SaveFlag); 405363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPaint paint; 406096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 407096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(255); 408363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPath path; 409363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger path.addCircle(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(2)); 41058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clipPath(path, SkRegion::kIntersect_Op, false); 41158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 41258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restore(); 41358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that stroked rect does not trigger a fresh frame 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 419096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kStroke_Style); 420096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(255); 42158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 42258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, !canvas->isFreshFrame()); 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify kSrcMode triggers a fresh frame even with transparent color 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paint; 428096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 429096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger paint.setAlpha(100); 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setXfermodeMode(SkXfermode::kSrc_Mode); 43158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(fullRect, paint); 43258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->isFreshFrame()); 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass MockDevice : public SkBitmapDevice { 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 4380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger MockDevice(const SkBitmap& bm) : SkBitmapDevice(bm) { 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBitmapCallCount = 0; 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void drawBitmap(const SkDraw&, const SkBitmap&, 44258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkMatrix&, const SkPaint&) SK_OVERRIDE { 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBitmapCallCount++; 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fDrawBitmapCallCount; 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Verifies that the deferred canvas triggers a flush when its memory 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// limit is exceeded 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasMemoryLimit(skiatest::Reporter* reporter) { 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.allocPixels(); 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MockDevice mockDevice(store); 456e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&mockDevice)); 45758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setMaxRecordingStorage(160000); 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap sourceImage; 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // 100 by 100 image, takes 40,000 bytes in memory 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImage.allocPixels(); 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 5; i++) { 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImage.notifyPixelsChanged(); // to force re-serialization 46658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImage, 0, 0, NULL); 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, mockDevice.fDrawBitmapCallCount == 4); 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass NotificationCounter : public SkDeferredCanvas::NotificationClient { 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NotificationCounter() { 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fPrepareForDrawCount = fStorageAllocatedChangedCount = 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlushedDrawCommandsCount = fSkippedPendingDrawCommandsCount = 0; 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void prepareForDraw() SK_OVERRIDE { 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fPrepareForDrawCount++; 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 482096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE { 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fStorageAllocatedChangedCount++; 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void flushedDrawCommands() SK_OVERRIDE { 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlushedDrawCommandsCount++; 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void skippedPendingDrawCommands() SK_OVERRIDE { 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSkippedPendingDrawCommandsCount++; 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fPrepareForDrawCount; 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fStorageAllocatedChangedCount; 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fFlushedDrawCommandsCount; 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fSkippedPendingDrawCommandsCount; 496096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 497096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerprivate: 498096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger typedef SkDeferredCanvas::NotificationClient INHERITED; 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasBitmapCaching(skiatest::Reporter* reporter) { 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.allocPixels(); 5050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NotificationCounter notificationCounter; 507e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 50858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setNotificationClient(¬ificationCounter); 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int imageCount = 2; 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap sourceImages[imageCount]; 51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < imageCount; i++) 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImages[i].setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImages[i].allocPixels(); 51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t bitmapSize = sourceImages[0].getSize(); 51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[0], 0, 0, NULL); 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fStorageAllocatedChangedCount); 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // stored bitmap + drawBitmap command 52358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > bitmapSize); 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // verify that nothing can be freed at this point 52658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, 0 == canvas->freeMemoryIfPossible(~0U)); 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // verify that flush leaves image in cache 52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount); 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 0 == notificationCounter.fPrepareForDrawCount); 53158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount); 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fPrepareForDrawCount); 53458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() >= bitmapSize); 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // verify that after a flush, cached image can be freed 53758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->freeMemoryIfPossible(~0U) >= bitmapSize); 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that caching works for avoiding multiple copies of the same bitmap 54058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[0], 0, 0, NULL); 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount); 54258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[0], 0, 0, NULL); 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount); 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount); 54558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < 2 * bitmapSize); 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify partial eviction based on bytesToFree 54858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[1], 0, 0, NULL); 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount); 55058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount); 55258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2 * bitmapSize); 55358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t bytesFreed = canvas->freeMemoryIfPossible(1); 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount); 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verifiy that partial purge works, image zero is in cache but not reffed by 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a pending draw, while image 1 is locked-in. 56058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->freeMemoryIfPossible(~0U); 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount); 56258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[0], 0, 0, NULL); 56358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 56458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[1], 0, 0, NULL); 56558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger bytesFreed = canvas->freeMemoryIfPossible(~0U); 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // only one bitmap should have been freed. 56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, bytesFreed >= bitmapSize); 56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, bytesFreed < 2*bitmapSize); 56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Clear for next test 57058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 57158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->freeMemoryIfPossible(~0U); 57258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < bitmapSize); 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify the image cache is sensitive to genID bumps 57558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[1], 0, 0, NULL); 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sourceImages[1].notifyPixelsChanged(); 57758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImages[1], 0, 0, NULL); 57858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2*bitmapSize); 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Verify that nothing in this test caused commands to be skipped 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 0 == notificationCounter.fSkippedPendingDrawCommandsCount); 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDeferredCanvasSkip(skiatest::Reporter* reporter) { 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap store; 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru store.allocPixels(); 5880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NotificationCounter notificationCounter; 590e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 59158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setNotificationClient(¬ificationCounter); 59258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(0x0); 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawCommandsCount); 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount); 59558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawCommandsCount); 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount); 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 601363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void TestDeferredCanvasBitmapShaderNoLeak(skiatest::Reporter* reporter) { 602363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // This is a regression test for crbug.com/155875 603363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // This test covers a code path that inserts bitmaps into the bitmap heap through the 604363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // flattening of SkBitmapProcShaders. The refcount in the bitmap heap is maintained through 605363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the flattening and unflattening of the shader. 606363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkBitmap store; 607363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 608363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger store.allocPixels(); 6090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 610e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 611363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // test will fail if nbIterations is not in sync with 612363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // BITMAPS_TO_KEEP in SkGPipeWrite.cpp 613363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const int nbIterations = 5; 614363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger size_t bytesAllocated = 0; 615363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for(int pass = 0; pass < 2; ++pass) { 616363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for(int i = 0; i < nbIterations; ++i) { 617363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPaint paint; 618363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkBitmap paintPattern; 619363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paintPattern.setConfig(SkBitmap::kARGB_8888_Config, 10, 10); 620363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paintPattern.allocPixels(); 621363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paint.setShader(SkNEW_ARGS(SkBitmapProcShader, 622363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (paintPattern, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)))->unref(); 62358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawPaint(paint); 62458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 625363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 626363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In the first pass, memory allocation should be monotonically increasing as 627363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the bitmap heap slots fill up. In the second pass memory allocation should be 628363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // stable as bitmap heap slots get recycled. 62958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t newBytesAllocated = canvas->storageAllocatedForRecording(); 630363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (pass == 0) { 631363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger REPORTER_ASSERT(reporter, newBytesAllocated > bytesAllocated); 632363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bytesAllocated = newBytesAllocated; 633363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 634363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger REPORTER_ASSERT(reporter, newBytesAllocated == bytesAllocated); 635363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 636363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 637363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 638363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // All cached resources should be evictable since last canvas call was flush() 63958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->freeMemoryIfPossible(~0U); 64058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, 0 == canvas->storageAllocatedForRecording()); 641363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 642363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 643363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic void TestDeferredCanvasBitmapSizeThreshold(skiatest::Reporter* reporter) { 644363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkBitmap store; 645363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 646363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger store.allocPixels(); 647363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 648363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkBitmap sourceImage; 649363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // 100 by 100 image, takes 40,000 bytes in memory 650363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sourceImage.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 651363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sourceImage.allocPixels(); 652363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 653363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // 1 under : should not store the image 654363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { 6550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 656e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 65758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setBitmapSizeThreshold(39999); 65858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImage, 0, 0, NULL); 65958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t newBytesAllocated = canvas->storageAllocatedForRecording(); 660363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger REPORTER_ASSERT(reporter, newBytesAllocated == 0); 661363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 662363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 663363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // exact value : should store the image 664363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { 6650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 666e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 66758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setBitmapSizeThreshold(40000); 66858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImage, 0, 0, NULL); 66958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t newBytesAllocated = canvas->storageAllocatedForRecording(); 670363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger REPORTER_ASSERT(reporter, newBytesAllocated > 0); 671363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 672363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 673363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // 1 over : should still store the image 674363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { 6750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 676e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 67758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setBitmapSizeThreshold(40001); 67858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawBitmap(sourceImage, 0, 0, NULL); 67958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t newBytesAllocated = canvas->storageAllocatedForRecording(); 680363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger REPORTER_ASSERT(reporter, newBytesAllocated > 0); 681363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 682363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 683363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 6847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 6857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergertypedef void* PixelPtr; 6867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// Returns an opaque pointer which, either points to a GrTexture or RAM pixel 6877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// buffer. Used to test pointer equality do determine whether a surface points 6887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// to the same pixel data storage as before. 6897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic PixelPtr getSurfacePixelPtr(SkSurface* surface, bool useGpu) { 6907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return useGpu ? surface->getCanvas()->getDevice()->accessBitmap(false).getTexture() : 6917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger surface->getCanvas()->getDevice()->accessBitmap(false).getPixels(); 6927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 6937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 6947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFactory* factory) { 6950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkImageInfo imageSpec = { 6967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10, // width 6977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10, // height 6980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kPMColor_SkColorType, 6990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kPremul_SkAlphaType 7007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger }; 7017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkSurface* surface; 7027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool useGpu = NULL != factory; 7037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if SK_SUPPORT_GPU 7047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (useGpu) { 7057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrContext* context = factory->get(GrContextFactory::kNative_GLContextType); 706910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (NULL == context) { 707910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger return; 708910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger } 709910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 7107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger surface = SkSurface::NewRenderTarget(context, imageSpec); 7117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 7127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger surface = SkSurface::NewRaster(imageSpec); 7137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 7147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else 7157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(!useGpu); 7167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger surface = SkSurface::NewRaster(imageSpec); 7177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 7187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(NULL != surface); 7197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkAutoTUnref<SkSurface> aur(surface); 720e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface)); 7217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 72258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkImage* image1 = canvas->newImageSnapshot(); 7237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkAutoTUnref<SkImage> aur_i1(image1); 7247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); 7257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // The following clear would normally trigger a copy on write, but 7267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // it won't because rendering is deferred. 72758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(SK_ColorBLACK); 7287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Obtaining a snapshot directly from the surface (as opposed to the 7297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // SkDeferredCanvas) will not trigger a flush of deferred draw operations 7307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // and will therefore return the same image as the previous snapshot. 7317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkImage* image2 = surface->newImageSnapshot(); 7327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkAutoTUnref<SkImage> aur_i2(image2); 7337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Images identical because of deferral 7347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID()); 7357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Now we obtain a snpshot via the deferred canvas, which triggers a flush. 7367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Because there is a pending clear, this will generate a different image. 73758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkImage* image3 = canvas->newImageSnapshot(); 7387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkAutoTUnref<SkImage> aur_i3(image3); 7397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID()); 7407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Verify that backing store is now a different buffer because of copy on 7417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // write 7427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PixelPtr pixels2 = getSurfacePixelPtr(surface, useGpu); 7437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, pixels1 != pixels2); 7447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Verify copy-on write with a draw operation that gets deferred by 7457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // the in order draw buffer. 7467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPaint paint; 74758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawPaint(paint); 74858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkImage* image4 = canvas->newImageSnapshot(); // implicit flush 7497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkAutoTUnref<SkImage> aur_i4(image4); 7507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID()); 7517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PixelPtr pixels3 = getSurfacePixelPtr(surface, useGpu); 7527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, pixels2 != pixels3); 7537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Verify that a direct canvas flush with a pending draw does not trigger 7547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // a copy on write when the surface is not sharing its buffer with an 7557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // SkImage. 75658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(SK_ColorWHITE); 75758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 7587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PixelPtr pixels4 = getSurfacePixelPtr(surface, useGpu); 75958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawPaint(paint); 76058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 7617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PixelPtr pixels5 = getSurfacePixelPtr(surface, useGpu); 7627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, pixels4 == pixels5); 7637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 7647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 765779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenbergerstatic void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContextFactory* factory) { 7660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkImageInfo imageSpec = { 767779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 10, // width 768779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 10, // height 7690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kPMColor_SkColorType, 7700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kPremul_SkAlphaType 771779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger }; 772779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkSurface* surface; 773779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkSurface* alternateSurface; 774779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger bool useGpu = NULL != factory; 775779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#if SK_SUPPORT_GPU 776779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if (useGpu) { 777779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrContext* context = factory->get(GrContextFactory::kNative_GLContextType); 778910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (NULL == context) { 779910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger return; 780910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger } 781779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger surface = SkSurface::NewRenderTarget(context, imageSpec); 782779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger alternateSurface = SkSurface::NewRenderTarget(context, imageSpec); 783779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } else { 784779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger surface = SkSurface::NewRaster(imageSpec); 785779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger alternateSurface = SkSurface::NewRaster(imageSpec); 786779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 787779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#else 788779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkASSERT(!useGpu); 789779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger surface = SkSurface::NewRaster(imageSpec); 790779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger alternateSurface = SkSurface::NewRaster(imageSpec); 791779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#endif 792779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkASSERT(NULL != surface); 793779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkASSERT(NULL != alternateSurface); 794779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkAutoTUnref<SkSurface> aur1(surface); 795779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkAutoTUnref<SkSurface> aur2(alternateSurface); 796779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu); 797779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger PixelPtr pixels2 = getSurfacePixelPtr(alternateSurface, useGpu); 798e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface)); 79958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); 80058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setSurface(alternateSurface); 80158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); 802779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID()); 803779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // Verify that none of the above operations triggered a surface copy on write. 804779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); 805779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) == pixels2); 806779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // Verify that a flushed draw command will trigger a copy on write on alternateSurface. 80758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clear(SK_ColorWHITE); 80858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->flush(); 809779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1); 810779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) != pixels2); 811779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger} 812779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 8137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporter) { 8147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkBitmap store; 8157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); 8167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger store.allocPixels(); 8170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapDevice device(store); 8187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger NotificationCounter notificationCounter; 819e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(&device)); 82058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->setNotificationClient(¬ificationCounter); 8210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkAutoTUnref<SkBaseDevice> secondaryDevice(canvas->createCompatibleDevice( 8227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkBitmap::kARGB_8888_Config, 10, 10, device.isOpaque())); 8237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkCanvas secondaryCanvas(secondaryDevice.get()); 8247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkRect rect = SkRect::MakeWH(5, 5); 8257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPaint paint; 8267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // After spawning a compatible canvas: 8277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // 1) Verify that secondary canvas is usable and does not report to the notification client. 8287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger secondaryCanvas.drawRect(rect, paint); 8297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount == 0); 8307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // 2) Verify that original canvas is usable and still reports to the notification client. 83158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawRect(rect, paint); 8327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount == 1); 8337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 8347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 8357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void TestDeferredCanvas(skiatest::Reporter* reporter, GrContextFactory* factory) { 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasBitmapAccess(reporter); 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasFlush(reporter); 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasFreshFrame(reporter); 83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasMemoryLimit(reporter); 84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasBitmapCaching(reporter); 84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestDeferredCanvasSkip(reporter); 842363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger TestDeferredCanvasBitmapShaderNoLeak(reporter); 843363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger TestDeferredCanvasBitmapSizeThreshold(reporter); 8447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger TestDeferredCanvasCreateCompatibleDevice(reporter); 845e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger TestDeferredCanvasWritePixelsToSurface(reporter); 8467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger TestDeferredCanvasSurface(reporter, NULL); 847779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger TestDeferredCanvasSetSurface(reporter, NULL); 8487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL != factory) { 8497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger TestDeferredCanvasSurface(reporter, factory); 850779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger TestDeferredCanvasSetSurface(reporter, factory); 8517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TestClassDef.h" 8557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerDEFINE_GPUTESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanvas) 856