1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBigPicture.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBBoxHierarchy.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurImageFilter.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorMatrixFilter.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorPriv.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDashPathEffect.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkData.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageGenerator.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageEncoder.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageGenerator.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMD5.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMiniRecorder.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPicture.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPictureRecorder.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPixelRef.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRectPriv.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRRect.h" 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRandom.h" 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRecord.h" 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h" 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h" 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h" 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkLumaColorFilter.h" 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorFilterImageFilter.h" 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void make_bm(SkBitmap* bm, int w, int h, SkColor color, bool immutable) { 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->allocN32Pixels(w, h); 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->eraseColor(color); 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (immutable) { 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm->setImmutable(); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Ensure that deleting an empty SkPicture does not assert. Asserts only fire 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// in debug mode, so only run in debug mode. 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_deleting_empty_picture() { 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Creates an SkPictureRecord 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recorder.beginRecording(0, 0); 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Turns that into an SkPicture 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Ceates a new SkPictureRecord 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recorder.beginRecording(0, 0); 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Ensure that serializing an empty picture does not assert. Likewise only runs in debug mode. 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_serializing_empty_picture() { 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recorder.beginRecording(0, 0); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDynamicMemoryWStream stream; 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->serialize(&stream); 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void rand_op(SkCanvas* canvas, SkRandom& rand) { 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect = SkRect::MakeWH(50, 50); 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar unit = rand.nextUScalar1(); 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (unit <= 0.3) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// SkDebugf("save\n"); 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (unit <= 0.6) { 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// SkDebugf("restore\n"); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (unit <= 0.9) { 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// SkDebugf("clip\n"); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(rect); 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// SkDebugf("draw\n"); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPaint(paint); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void set_canvas_to_save_count_4(SkCanvas* canvas) { 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restoreToCount(1); 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * A canvas that records the number of saves, saveLayers and restores. 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SaveCountingCanvas : public SkCanvas { 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SaveCountingCanvas(int width, int height) 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(width, height) 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fSaveCount(0) 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fSaveLayerCount(0) 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fRestoreCount(0){ 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override { 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fSaveLayerCount; 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->INHERITED::getSaveLayerStrategy(rec); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void willSave() override { 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fSaveCount; 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::willSave(); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void willRestore() override { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fRestoreCount; 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::willRestore(); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int getSaveCount() const { return fSaveCount; } 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int getSaveLayerCount() const { return fSaveLayerCount; } 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int getRestoreCount() const { return fRestoreCount; } 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int fSaveCount; 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int fSaveLayerCount; 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int fRestoreCount; 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef SkCanvas INHERITED; 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid check_save_state(skiatest::Reporter* reporter, SkPicture* picture, 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int numSaves, unsigned int numSaveLayers, 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int numRestores) { 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SaveCountingCanvas canvas(SkScalarCeilToInt(picture->cullRect().width()), 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarCeilToInt(picture->cullRect().height())); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->playback(&canvas); 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Optimizations may have removed these, 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // so expect to have seen no more than num{Saves,SaveLayers,Restores}. 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, numSaves >= canvas.getSaveCount()); 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, numSaveLayers >= canvas.getSaveLayerCount()); 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, numRestores >= canvas.getRestoreCount()); 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This class exists so SkPicture can friend it and give it access to 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// the 'partialReplay' method. 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPictureRecorderReplayTester { 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static sk_sp<SkPicture> Copy(SkPictureRecorder* recorder) { 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder2; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder2.beginRecording(10, 10); 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recorder->partialReplay(canvas); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return recorder2.finishRecordingAsPicture(); 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void create_imbalance(SkCanvas* canvas) { 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect clipRect = SkRect::MakeWH(2, 2); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect drawRect = SkRect::MakeWH(10, 10); 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(clipRect, kReplace_SkClipOp); 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(1.0f, 1.0f); 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint p; 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.setColor(SK_ColorGREEN); 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(drawRect, p); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // no restore 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This tests that replaying a potentially unbalanced picture into a canvas 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// doesn't affect the canvas' save count or matrix/clip state. 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void check_balance(skiatest::Reporter* reporter, SkPicture* picture) { 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap bm; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm.allocN32Pixels(4, 3); 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas canvas(bm); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int beforeSaveCount = canvas.getSaveCount(); 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix beforeMatrix = canvas.getTotalMatrix(); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect beforeClip = canvas.getLocalClipBounds(); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas.drawPicture(picture); 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, beforeSaveCount == canvas.getSaveCount()); 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, beforeMatrix == canvas.getTotalMatrix()); 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect afterClip = canvas.getLocalClipBounds(); 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, afterClip == beforeClip); 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test out SkPictureRecorder::partialReplay 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(PictureRecorder_replay, reporter) { 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // check save/saveLayer state 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->saveLayer(nullptr, nullptr); 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> copy(SkPictureRecorderReplayTester::Copy(&recorder)); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The extra save and restore comes from the Copy process. 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_save_state(reporter, copy.get(), 2, 1, 3); 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->saveLayer(nullptr, nullptr); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> final(recorder.finishRecordingAsPicture()); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_save_state(reporter, final.get(), 1, 2, 3); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The copy shouldn't pick up any operations added after it was made 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_save_state(reporter, copy.get(), 2, 1, 3); 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Recreate the Android partialReplay test case 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(4, 3, nullptr, 0); 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot create_imbalance(canvas); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int expectedSaveCount = canvas->getSaveCount(); 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> copy(SkPictureRecorderReplayTester::Copy(&recorder)); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_balance(reporter, copy.get()); 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, expectedSaveCount = canvas->getSaveCount()); 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // End the recording of source to test the picture finalization 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // process isn't complicated by the partialReplay step 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> final(recorder.finishRecordingAsPicture()); 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_unbalanced_save_restores(skiatest::Reporter* reporter) { 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas testCanvas(100, 100); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot set_canvas_to_save_count_4(&testCanvas); 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount()); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect = SkRect::MakeLTRB(-10000000, -10000000, 10000000, 10000000); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Create picture with 2 unbalanced saves 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(10, 10); 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(rect, paint); 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(10, 10); 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(rect, paint); 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> extraSavePicture(recorder.finishRecordingAsPicture()); 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testCanvas.drawPicture(extraSavePicture); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount()); 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot set_canvas_to_save_count_4(&testCanvas); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Create picture with 2 unbalanced restores 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(10, 10); 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(rect, paint); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(10, 10); 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(rect, paint); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> extraRestorePicture(recorder.finishRecordingAsPicture()); 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testCanvas.drawPicture(extraRestorePicture); 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount()); 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot set_canvas_to_save_count_4(&testCanvas); 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->translate(10, 10); 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(rect, paint); 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> noSavePicture(recorder.finishRecordingAsPicture()); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot testCanvas.drawPicture(noSavePicture); 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount()); 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, testCanvas.getTotalMatrix().isIdentity()); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_peephole() { 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRandom rand; 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = 0; j < 100; j++) { 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRandom rand2(rand); // remember the seed 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 1000; ++i) { 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rand_op(canvas, rand); 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rand = rand2; 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect = SkRect::MakeWH(50, 50); 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 100; ++i) { 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (canvas->getSaveCount() > 1) { 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(rect); 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_DEBUG 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Only test this is in release mode. We deliberately crash in debug mode, since a valid caller 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// should never do this. 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_bad_bitmap() { 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This bitmap has a width and height but no pixels. As a result, attempting to record it will 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // fail. 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap bm; 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm.setInfo(SkImageInfo::MakeN32Premul(100, 100)); 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* recordingCanvas = recorder.beginRecording(100, 100); 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recordingCanvas->drawBitmap(bm, 0, 0); 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas canvas; 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas.drawPicture(picture); 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_clip_bound_opt(skiatest::Reporter* reporter) { 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Test for crbug.com/229011 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(4), SkIntToScalar(4), 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(2), SkIntToScalar(2)); 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect2 = SkRect::MakeXYWH(SkIntToScalar(7), SkIntToScalar(7), 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(1), SkIntToScalar(1)); 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rect3 = SkRect::MakeXYWH(SkIntToScalar(6), SkIntToScalar(6), 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(1), SkIntToScalar(1)); 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath invPath; 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot invPath.addOval(rect1); 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot invPath.setFillType(SkPath::kInverseEvenOdd_FillType); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.addOval(rect2); 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path2; 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path2.addOval(rect3); 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect clipBounds; 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Testing conservative-raster-clip that is enabled by PictureRecord 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(invPath); 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path); 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(invPath); 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path); 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(invPath, kUnion_SkClipOp); 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path, kDifference_SkClipOp); 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fLeft); 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == clipBounds.fTop); 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fBottom); 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 10 == clipBounds.fRight); 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path, kReverseDifference_SkClipOp); 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // True clip is actually empty in this case, but the best 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // determination we can make using only bounds as input is that the 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // clip is included in the bounds of 'path'. 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 7 == clipBounds.fLeft); 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 7 == clipBounds.fTop); 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path, kIntersect_SkClipOp); 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(path2, kXOR_SkClipOp); 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipBounds = canvas->getDeviceClipBounds(); 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 6 == clipBounds.fLeft); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 6 == clipBounds.fTop); 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fBottom); 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 8 == clipBounds.fRight); 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_cull_rect_reset(skiatest::Reporter* reporter) { 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bounds = SkRect::MakeWH(10, 10); 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRTreeFactory factory; 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(bounds, &factory); 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds = SkRect::MakeWH(100, 100); 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(bounds, paint); 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(bounds, paint); 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> p(recorder.finishRecordingAsPictureWithCull(bounds)); 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBigPicture* picture = p->asSkBigPicture(); 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, picture); 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect finalCullRect = picture->cullRect(); 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == finalCullRect.fLeft); 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == finalCullRect.fTop); 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 100 == finalCullRect.fBottom); 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 100 == finalCullRect.fRight); 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBBoxHierarchy* pictureBBH = picture->bbh(); 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bbhCullRect = pictureBBH->getRootBound(); 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == bbhCullRect.fLeft); 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0 == bbhCullRect.fTop); 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 100 == bbhCullRect.fBottom); 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 100 == bbhCullRect.fRight); 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * A canvas that records the number of clip commands. 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ClipCountingCanvas : public SkCanvas { 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ClipCountingCanvas(int width, int height) 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(width, height) 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fClipCount(0){ 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onClipRect(const SkRect& r, SkClipOp op, ClipEdgeStyle edgeStyle) override { 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fClipCount += 1; 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::onClipRect(r, op, edgeStyle); 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle)override { 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fClipCount += 1; 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::onClipRRect(rrect, op, edgeStyle); 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) override { 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fClipCount += 1; 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::onClipPath(path, op, edgeStyle); 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onClipRegion(const SkRegion& deviceRgn, SkClipOp op) override { 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fClipCount += 1; 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::onClipRegion(deviceRgn, op); 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned getClipCount() const { return fClipCount; } 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned fClipCount; 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef SkCanvas INHERITED; 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_clip_expansion(skiatest::Reporter* reporter) { 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(SkRect::MakeEmpty(), kReplace_SkClipOp); 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The following expanding clip should not be skipped. 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(SkRect::MakeXYWH(4, 4, 3, 3), kUnion_SkClipOp); 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Draw something so the optimizer doesn't just fold the world. 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint p; 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.setColor(SK_ColorBLUE); 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPaint(p); 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ClipCountingCanvas testCanvas(10, 10); 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->playback(&testCanvas); 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Both clips should be present on playback. 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, testCanvas.getClipCount() == 2); 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_gen_id(skiatest::Reporter* reporter) { 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot recorder.beginRecording(0, 0); 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> empty(recorder.finishRecordingAsPicture()); 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Empty pictures should still have a valid ID 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, empty->uniqueID() != SK_InvalidGenID); 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(1, 1); 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawColor(SK_ColorWHITE); 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> hasData(recorder.finishRecordingAsPicture()); 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // picture should have a non-zero id after recording 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, hasData->uniqueID() != SK_InvalidGenID); 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // both pictures should have different ids 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, hasData->uniqueID() != empty->uniqueID()); 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_typeface(skiatest::Reporter* reporter) { 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(10, 10); 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setTypeface(SkTypeface::MakeFromName("Arial", SkFontStyle::Italic())); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawString("Q", 0, 10, paint); 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDynamicMemoryWStream stream; 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->serialize(&stream); 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture, reporter) { 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_typeface(reporter); 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_deleting_empty_picture(); 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_serializing_empty_picture(); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_bad_bitmap(); 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_unbalanced_save_restores(reporter); 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_peephole(); 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_clip_bound_opt(reporter); 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_clip_expansion(reporter); 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_gen_id(reporter); 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_cull_rect_reset(reporter); 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) { 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint paint; 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect rect = { 5.0f, 5.0f, 8.0f, 8.0f }; 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect irect = { 2, 2, 3, 3 }; 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int divs[] = { 2, 3 }; 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas::Lattice lattice; 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot lattice.fXCount = lattice.fYCount = 2; 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot lattice.fXDivs = lattice.fYDivs = divs; 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Don't care what these record, as long as they're legal. 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(bitmap, 0.0f, 0.0f, &paint); 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmapRect(bitmap, rect, rect, &paint, SkCanvas::kStrict_SrcRectConstraint); 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmapNine(bitmap, irect, rect, &paint); 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(bitmap, 1, 1); // drawSprite 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmapLattice(bitmap, lattice, rect, &paint); 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_draw_bitmaps(SkCanvas* canvas) { 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap empty; 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw_bitmaps(empty, canvas); 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot empty.setInfo(SkImageInfo::MakeN32Premul(10, 10)); 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw_bitmaps(empty, canvas); 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_EmptyBitmap, r) { 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_draw_bitmaps(recorder.beginRecording(10, 10)); 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Canvas_EmptyBitmap, r) { 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap dst; 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dst.allocN32Pixels(10, 10); 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas canvas(dst); 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test_draw_bitmaps(&canvas); 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(DontOptimizeSaveLayerDrawDrawRestore, reporter) { 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This test is from crbug.com/344987. 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The commands are: 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // saveLayer with paint that modifies alpha 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // drawBitmapRect 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // drawBitmapRect 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // restore 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The bug was that this structure was modified so that: 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // - The saveLayer and restore were eliminated 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // - The alpha was only applied to the first drawBitmapRectToRect 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This test draws blue and red squares inside a 50% transparent 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // layer. Both colours should show up muted. 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When the bug is present, the red square (the second bitmap) 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // shows upwith full opacity. 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap blueBM; 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_bm(&blueBM, 100, 100, SkColorSetARGB(255, 0, 0, 255), true); 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap redBM; 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_bm(&redBM, 100, 100, SkColorSetARGB(255, 255, 0, 0), true); 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint semiTransparent; 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot semiTransparent.setAlpha(0x80); 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(100, 100); 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawColor(0); 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->saveLayer(nullptr, &semiTransparent); 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(blueBM, 25, 25); 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(redBM, 50, 50); 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Now replay the picture back on another canvas 644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // and check a couple of its pixels. 645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap replayBM; 646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot make_bm(&replayBM, 100, 100, SK_ColorBLACK, false); 647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas replayCanvas(replayBM); 648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->playback(&replayCanvas); 649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot replayCanvas.flush(); 650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // With the bug present, at (55, 55) we would get a fully opaque red 652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // intead of a dark red. 653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, replayBM.getColor(30, 30) == 0xff000080); 654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, replayBM.getColor(55, 55) == 0xff800000); 655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct CountingBBH : public SkBBoxHierarchy { 658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mutable int searchCalls; 659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rootBound; 660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CountingBBH(const SkRect& bound) : searchCalls(0), rootBound(bound) {} 662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void search(const SkRect& query, SkTDArray<int>* results) const override { 664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->searchCalls++; 665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void insert(const SkRect[], int) override {} 668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual size_t bytesUsed() const override { return 0; } 669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect getRootBound() const override { return rootBound; } 670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SpoonFedBBHFactory : public SkBBHFactory { 673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit SpoonFedBBHFactory(SkBBoxHierarchy* bbh) : fBBH(bbh) {} 675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBBoxHierarchy* operator()(const SkRect&) const override { 676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkRef(fBBH); 677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBBoxHierarchy* fBBH; 680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// When the canvas clip covers the full picture, we don't need to call the BBH. 683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_SkipBBH, r) { 684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bound = SkRect::MakeWH(320, 240); 685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CountingBBH bbh(bound); 686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SpoonFedBBHFactory factory(&bbh); 687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* c = recorder.beginRecording(bound, &factory); 690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Record a few ops so we don't hit a small- or empty- picture optimization. 691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot c->drawRect(bound, SkPaint()); 692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot c->drawRect(bound, SkPaint()); 693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas big(640, 480), small(300, 200); 696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->playback(&big); 698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, bbh.searchCalls == 0); 699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->playback(&small); 701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, bbh.searchCalls == 1); 702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_BitmapLeak, r) { 705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap mut, immut; 706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mut.allocN32Pixels(300, 200); 707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot immut.allocN32Pixels(300, 200); 708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot immut.setImmutable(); 709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!mut.isImmutable()); 710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(immut.isImmutable()); 711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // No one can hold a ref on our pixels yet. 713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, mut.pixelRef()->unique()); 714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, immut.pixelRef()->unique()); 715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> pic; 717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // we want the recorder to go out of scope before our subsequent checks, so we 719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // place it inside local braces. 720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder rec; 721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = rec.beginRecording(1920, 1200); 722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(mut, 0, 0); 723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawBitmap(immut, 800, 600); 724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pic = rec.finishRecordingAsPicture(); 725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The picture shares the immutable pixels but copies the mutable ones. 728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, mut.pixelRef()->unique()); 729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, !immut.pixelRef()->unique()); 730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When the picture goes away, it's just our bitmaps holding the refs. 732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pic = nullptr; 733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, mut.pixelRef()->unique()); 734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, immut.pixelRef()->unique()); 735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// getRecordingCanvas() should return a SkCanvas when recording, null when not recording. 738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_getRecordingCanvas, r) { 739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder rec; 740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, !rec.getRecordingCanvas()); 741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 3; i++) { 742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rec.beginRecording(100, 100); 743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, rec.getRecordingCanvas()); 744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rec.finishRecordingAsPicture(); 745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, !rec.getRecordingCanvas()); 746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(MiniRecorderLeftHanging, r) { 750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Any shader or other ref-counted effect will do just fine here. 751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setShader(SkShader::MakeColorShader(SK_ColorRED)); 753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMiniRecorder rec; 755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, rec.drawRect(SkRect::MakeWH(20,30), paint)); 756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Don't call rec.detachPicture(). Test succeeds by not asserting or leaking the shader. 757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_preserveCullRect, r) { 760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* c = recorder.beginRecording(SkRect::MakeLTRB(1, 2, 3, 4)); 763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot c->clear(SK_ColorCYAN); 764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDynamicMemoryWStream wstream; 767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot picture->serialize(&wstream); 768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<SkStream> rstream(wstream.detachAsStream()); 770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> deserializedPicture(SkPicture::MakeFromStream(rstream.get())); 771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, deserializedPicture != nullptr); 773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, deserializedPicture->cullRect().left() == 1); 774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, deserializedPicture->cullRect().top() == 2); 775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, deserializedPicture->cullRect().right() == 3); 776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, deserializedPicture->cullRect().bottom() == 4); 777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// If we record bounded ops into a picture with a big cull and calculate the 781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// bounds of those ops, we should trim down the picture cull to the ops' bounds. 782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// If we're not using an SkBBH, we shouldn't change it. 783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_UpdatedCull_1, r) { 784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Testing 1 draw exercises SkMiniPicture. 785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRTreeFactory factory; 786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto canvas = recorder.beginRecording(SkRectPriv::MakeLargest(), &factory); 789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(20,20), SkPaint{}); 790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto pic = recorder.finishRecordingAsPicture(); 791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->cullRect() == SkRect::MakeWH(20,20)); 792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas = recorder.beginRecording(SkRectPriv::MakeLargest()); 794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(20,20), SkPaint{}); 795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pic = recorder.finishRecordingAsPicture(); 796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->cullRect() == SkRectPriv::MakeLargest()); 797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_UpdatedCull_2, r) { 799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Testing >1 draw exercises SkBigPicture. 800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRTreeFactory factory; 801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto canvas = recorder.beginRecording(SkRectPriv::MakeLargest(), &factory); 804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(20,20), SkPaint{}); 805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(10,40), SkPaint{}); 806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto pic = recorder.finishRecordingAsPicture(); 807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->cullRect() == SkRect::MakeWH(20,40)); 808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas = recorder.beginRecording(SkRectPriv::MakeLargest()); 810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(20,20), SkPaint{}); 811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeWH(10,40), SkPaint{}); 812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pic = recorder.finishRecordingAsPicture(); 813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->cullRect() == SkRectPriv::MakeLargest()); 814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_RecordsFlush, r) { 817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto canvas = recorder.beginRecording(SkRect::MakeWH(100,100)); 820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 10; i++) { 821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clear(0); 822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int j = 0; j < 10; j++) { 823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(SkRect::MakeXYWH(i*10,j*10,10,10), SkPaint()); 824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->flush(); 826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Did we record the flushes? 829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto pic = recorder.finishRecordingAsPicture(); 830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->approximateOpCount() == 120); // 10 clears, 100 draws, 10 flushes 831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Do we serialize and deserialize flushes? 833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto skp = pic->serialize(); 834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto back = SkPicture::MakeFromData(skp->data(), skp->size()); 835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, back->approximateOpCount() == pic->approximateOpCount()); 836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Placeholder, r) { 839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect cull = { 0,0, 10,20 }; 840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Each placeholder is unique. 842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> p1 = SkPicture::MakePlaceholder(cull), 843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p2 = SkPicture::MakePlaceholder(cull); 844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, p1->cullRect() == p2->cullRect()); 845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, p1->cullRect() == cull); 846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, p1->uniqueID() != p2->uniqueID()); 847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Placeholders are never unrolled by SkCanvas (while other small pictures may be). 849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder recorder; 850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas* canvas = recorder.beginRecording(cull); 851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPicture(p1); 852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPicture(p2); 853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture(); 854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(r, pic->approximateOpCount() == 2); 855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(Picture_empty_serial, reporter) { 858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPictureRecorder rec; 859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (void)rec.beginRecording(10, 10); 860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto pic = rec.finishRecordingAsPicture(); 861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, pic); 862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto data = pic->serialize(); 864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, data); 865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto pic2 = SkPicture::MakeFromData(data->data(), data->size()); 867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, pic2); 868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 870