1327f905d2cb0d37c302d651d8f2b17ea56368467dneto/* 2327f905d2cb0d37c302d651d8f2b17ea56368467dneto * Copyright 2014 Google Inc. 3327f905d2cb0d37c302d651d8f2b17ea56368467dneto * 4327f905d2cb0d37c302d651d8f2b17ea56368467dneto * Use of this source code is governed by a BSD-style license that can be 5327f905d2cb0d37c302d651d8f2b17ea56368467dneto * found in the LICENSE file. 6327f905d2cb0d37c302d651d8f2b17ea56368467dneto */ 7327f905d2cb0d37c302d651d8f2b17ea56368467dneto 8327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "Test.h" 9327f905d2cb0d37c302d651d8f2b17ea56368467dneto 10327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/core/SkCanvas.h" 11327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/core/SkPicture.h" 12327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/core/SkStream.h" 13327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/core/SkString.h" 14327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/record/SkRecording.h" 15327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include "../include/core/SkPictureRecorder.h" 16327f905d2cb0d37c302d651d8f2b17ea56368467dneto#include <cstring> 17327f905d2cb0d37c302d651d8f2b17ea56368467dneto 18327f905d2cb0d37c302d651d8f2b17ea56368467dneto// Verify that replay of a recording into a clipped canvas 19327f905d2cb0d37c302d651d8f2b17ea56368467dneto// produces the correct bitmap. 20327f905d2cb0d37c302d651d8f2b17ea56368467dneto// This arose from http://crbug.com/401593 which has 21327f905d2cb0d37c302d651d8f2b17ea56368467dneto// https://code.google.com/p/skia/issues/detail?id=1291 as its root cause. 22327f905d2cb0d37c302d651d8f2b17ea56368467dneto 23327f905d2cb0d37c302d651d8f2b17ea56368467dneto 24327f905d2cb0d37c302d651d8f2b17ea56368467dnetonamespace { 25327f905d2cb0d37c302d651d8f2b17ea56368467dneto 26327f905d2cb0d37c302d651d8f2b17ea56368467dnetoclass Drawer { 27327f905d2cb0d37c302d651d8f2b17ea56368467dneto public: 28327f905d2cb0d37c302d651d8f2b17ea56368467dneto explicit Drawer() 29327f905d2cb0d37c302d651d8f2b17ea56368467dneto : fImageInfo(SkImageInfo::MakeN32Premul(200,100)) 30327f905d2cb0d37c302d651d8f2b17ea56368467dneto { 31327f905d2cb0d37c302d651d8f2b17ea56368467dneto fCircleBM.allocPixels( SkImageInfo::MakeN32Premul(100,100) ); 32327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas canvas(fCircleBM); 33327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas.clear(0xffffffff); 34327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPaint circlePaint; 35327f905d2cb0d37c302d651d8f2b17ea56368467dneto circlePaint.setColor(0xff000000); 36327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas.drawCircle(50,50,50,circlePaint); 37327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 38327f905d2cb0d37c302d651d8f2b17ea56368467dneto 39327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkImageInfo& imageInfo() const { return fImageInfo; } 40327f905d2cb0d37c302d651d8f2b17ea56368467dneto 41327f905d2cb0d37c302d651d8f2b17ea56368467dneto void draw(SkCanvas* canvas, const SkRect& clipRect, SkXfermode::Mode mode) const { 42327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPaint greenPaint; 43327f905d2cb0d37c302d651d8f2b17ea56368467dneto greenPaint.setColor(0xff008000); 44327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPaint blackPaint; 45327f905d2cb0d37c302d651d8f2b17ea56368467dneto blackPaint.setColor(0xff000000); 46327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPaint whitePaint; 47327f905d2cb0d37c302d651d8f2b17ea56368467dneto whitePaint.setColor(0xffffffff); 48327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPaint layerPaint; 49327f905d2cb0d37c302d651d8f2b17ea56368467dneto layerPaint.setColor(0xff000000); 50327f905d2cb0d37c302d651d8f2b17ea56368467dneto layerPaint.setXfermodeMode(mode); 51327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fImageInfo.width()),SkIntToScalar(fImageInfo.height()))); 52327f905d2cb0d37c302d651d8f2b17ea56368467dneto 53327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->clipRect(clipRect); 54327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->clear(0xff000000); 55327f905d2cb0d37c302d651d8f2b17ea56368467dneto 56327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->saveLayer(NULL,&blackPaint); 57327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->drawRect(canvasRect,greenPaint); 58327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->saveLayer(NULL,&layerPaint); 59327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->drawBitmapRect(fCircleBM,SkRect::MakeXYWH(20,20,60,60),&blackPaint); 60327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->restore(); 61327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas->restore(); 62327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 63327f905d2cb0d37c302d651d8f2b17ea56368467dneto 64327f905d2cb0d37c302d651d8f2b17ea56368467dneto private: 65327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkImageInfo fImageInfo; 66327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkBitmap fCircleBM; 67327f905d2cb0d37c302d651d8f2b17ea56368467dneto}; 68327f905d2cb0d37c302d651d8f2b17ea56368467dneto 69327f905d2cb0d37c302d651d8f2b17ea56368467dnetoclass RecordingStrategy { 70327f905d2cb0d37c302d651d8f2b17ea56368467dneto public: 71327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual ~RecordingStrategy() {} 72327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual void init(const SkImageInfo&) = 0; 73327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual const SkBitmap& recordAndReplay(const Drawer& drawer, 74327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkRect& intoClip, 75327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkXfermode::Mode) = 0; 76327f905d2cb0d37c302d651d8f2b17ea56368467dneto}; 77327f905d2cb0d37c302d651d8f2b17ea56368467dneto 78327f905d2cb0d37c302d651d8f2b17ea56368467dnetoclass BitmapBackedCanvasStrategy : public RecordingStrategy { 79327f905d2cb0d37c302d651d8f2b17ea56368467dneto // This version just draws into a bitmap-backed canvas. 80327f905d2cb0d37c302d651d8f2b17ea56368467dneto public: 81327f905d2cb0d37c302d651d8f2b17ea56368467dneto BitmapBackedCanvasStrategy() {} 82327f905d2cb0d37c302d651d8f2b17ea56368467dneto 83327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual void init(const SkImageInfo& imageInfo) { 84327f905d2cb0d37c302d651d8f2b17ea56368467dneto fBitmap.allocPixels(imageInfo); 85327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 86327f905d2cb0d37c302d651d8f2b17ea56368467dneto 87327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual const SkBitmap& recordAndReplay(const Drawer& drawer, 88327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkRect& intoClip, 89327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkXfermode::Mode mode) { 90327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas canvas(fBitmap); 91327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas.clear(0xffffffff); 92327f905d2cb0d37c302d651d8f2b17ea56368467dneto // Note that the scene is drawn just into the clipped region! 93327f905d2cb0d37c302d651d8f2b17ea56368467dneto canvas.clipRect(intoClip); 94327f905d2cb0d37c302d651d8f2b17ea56368467dneto drawer.draw(&canvas, intoClip, mode); // Shouild be canvas-wide... 95327f905d2cb0d37c302d651d8f2b17ea56368467dneto return fBitmap; 96327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 97327f905d2cb0d37c302d651d8f2b17ea56368467dneto 98327f905d2cb0d37c302d651d8f2b17ea56368467dneto private: 99327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkBitmap fBitmap; 100327f905d2cb0d37c302d651d8f2b17ea56368467dneto}; 101327f905d2cb0d37c302d651d8f2b17ea56368467dneto 102327f905d2cb0d37c302d651d8f2b17ea56368467dnetoclass DeprecatedRecorderStrategy : public RecordingStrategy { 103327f905d2cb0d37c302d651d8f2b17ea56368467dneto // This version draws the entire scene into an SkPictureRecorder, 104327f905d2cb0d37c302d651d8f2b17ea56368467dneto // using the deprecated recording backend. 105327f905d2cb0d37c302d651d8f2b17ea56368467dneto // Then it then replays the scene through a clip rectangle. 106327f905d2cb0d37c302d651d8f2b17ea56368467dneto // This backend proved to be buggy. 107327f905d2cb0d37c302d651d8f2b17ea56368467dneto public: 108327f905d2cb0d37c302d651d8f2b17ea56368467dneto DeprecatedRecorderStrategy() {} 109327f905d2cb0d37c302d651d8f2b17ea56368467dneto 110327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual void init(const SkImageInfo& imageInfo) { 111327f905d2cb0d37c302d651d8f2b17ea56368467dneto fBitmap.allocPixels(imageInfo); 112327f905d2cb0d37c302d651d8f2b17ea56368467dneto fWidth = imageInfo.width(); 113327f905d2cb0d37c302d651d8f2b17ea56368467dneto fHeight= imageInfo.height(); 114327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 115327f905d2cb0d37c302d651d8f2b17ea56368467dneto 116327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual const SkBitmap& recordAndReplay(const Drawer& drawer, 117327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkRect& intoClip, 118327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkXfermode::Mode mode) { 119327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkTileGridFactory::TileGridInfo tileGridInfo = { {100,100}, {0,0}, {0,0} }; 120327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkTileGridFactory factory(tileGridInfo); 121327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPictureRecorder recorder; 122327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fWidth),SkIntToScalar(fHeight))); 123327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas* canvas = recorder.DEPRECATED_beginRecording( SkIntToScalar(fWidth), SkIntToScalar(fHeight), &factory); 124327f905d2cb0d37c302d651d8f2b17ea56368467dneto drawer.draw(canvas, canvasRect, mode); 125327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkAutoTDelete<SkPicture> picture(recorder.endRecording()); 126327f905d2cb0d37c302d651d8f2b17ea56368467dneto 127327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas replayCanvas(fBitmap); 128327f905d2cb0d37c302d651d8f2b17ea56368467dneto replayCanvas.clear(0xffffffff); 129327f905d2cb0d37c302d651d8f2b17ea56368467dneto replayCanvas.clipRect(intoClip); 130327f905d2cb0d37c302d651d8f2b17ea56368467dneto picture->playback(&replayCanvas); 131327f905d2cb0d37c302d651d8f2b17ea56368467dneto 132327f905d2cb0d37c302d651d8f2b17ea56368467dneto return fBitmap; 133327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 134327f905d2cb0d37c302d651d8f2b17ea56368467dneto 135327f905d2cb0d37c302d651d8f2b17ea56368467dneto private: 136327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkBitmap fBitmap; 137327f905d2cb0d37c302d651d8f2b17ea56368467dneto int fWidth; 138327f905d2cb0d37c302d651d8f2b17ea56368467dneto int fHeight; 139327f905d2cb0d37c302d651d8f2b17ea56368467dneto}; 140327f905d2cb0d37c302d651d8f2b17ea56368467dneto 141327f905d2cb0d37c302d651d8f2b17ea56368467dnetoclass NewRecordingStrategy : public RecordingStrategy { 142327f905d2cb0d37c302d651d8f2b17ea56368467dneto // This version draws the entire scene into an SkPictureRecorder, 143327f905d2cb0d37c302d651d8f2b17ea56368467dneto // using the new recording backend. 144327f905d2cb0d37c302d651d8f2b17ea56368467dneto // Then it then replays the scene through a clip rectangle. 145327f905d2cb0d37c302d651d8f2b17ea56368467dneto // This backend proved to be buggy. 146327f905d2cb0d37c302d651d8f2b17ea56368467dneto public: 147327f905d2cb0d37c302d651d8f2b17ea56368467dneto NewRecordingStrategy() {} 148327f905d2cb0d37c302d651d8f2b17ea56368467dneto 149327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual void init(const SkImageInfo& imageInfo) { 150327f905d2cb0d37c302d651d8f2b17ea56368467dneto fBitmap.allocPixels(imageInfo); 151327f905d2cb0d37c302d651d8f2b17ea56368467dneto fWidth = imageInfo.width(); 152327f905d2cb0d37c302d651d8f2b17ea56368467dneto fHeight= imageInfo.height(); 153327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 154327f905d2cb0d37c302d651d8f2b17ea56368467dneto 155327f905d2cb0d37c302d651d8f2b17ea56368467dneto virtual const SkBitmap& recordAndReplay(const Drawer& drawer, 156327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkRect& intoClip, 157327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkXfermode::Mode mode) { 158327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkTileGridFactory::TileGridInfo tileGridInfo = { {100,100}, {0,0}, {0,0} }; 159327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkTileGridFactory factory(tileGridInfo); 160327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkPictureRecorder recorder; 161327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fWidth),SkIntToScalar(fHeight))); 162327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas* canvas = recorder.EXPERIMENTAL_beginRecording( SkIntToScalar(fWidth), SkIntToScalar(fHeight), &factory); 163327f905d2cb0d37c302d651d8f2b17ea56368467dneto 164327f905d2cb0d37c302d651d8f2b17ea56368467dneto drawer.draw(canvas, canvasRect, mode); 165327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkAutoTDelete<SkPicture> picture(recorder.endRecording()); 166327f905d2cb0d37c302d651d8f2b17ea56368467dneto 167327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkCanvas replayCanvas(fBitmap); 168327f905d2cb0d37c302d651d8f2b17ea56368467dneto replayCanvas.clear(0xffffffff); 169327f905d2cb0d37c302d651d8f2b17ea56368467dneto replayCanvas.clipRect(intoClip); 170327f905d2cb0d37c302d651d8f2b17ea56368467dneto picture->playback(&replayCanvas); 171327f905d2cb0d37c302d651d8f2b17ea56368467dneto return fBitmap; 172327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 173327f905d2cb0d37c302d651d8f2b17ea56368467dneto 174327f905d2cb0d37c302d651d8f2b17ea56368467dneto private: 175327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkBitmap fBitmap; 176327f905d2cb0d37c302d651d8f2b17ea56368467dneto int fWidth; 177327f905d2cb0d37c302d651d8f2b17ea56368467dneto int fHeight; 178327f905d2cb0d37c302d651d8f2b17ea56368467dneto}; 179327f905d2cb0d37c302d651d8f2b17ea56368467dneto 180327f905d2cb0d37c302d651d8f2b17ea56368467dneto} 181327f905d2cb0d37c302d651d8f2b17ea56368467dneto 182327f905d2cb0d37c302d651d8f2b17ea56368467dneto 183327f905d2cb0d37c302d651d8f2b17ea56368467dneto 184327f905d2cb0d37c302d651d8f2b17ea56368467dnetoDEF_TEST(SkRecordingAccuracyXfermode, reporter) { 185327f905d2cb0d37c302d651d8f2b17ea56368467dneto#define FINEGRAIN 0 186327f905d2cb0d37c302d651d8f2b17ea56368467dneto 187327f905d2cb0d37c302d651d8f2b17ea56368467dneto const Drawer drawer; 188327f905d2cb0d37c302d651d8f2b17ea56368467dneto 189327f905d2cb0d37c302d651d8f2b17ea56368467dneto BitmapBackedCanvasStrategy golden; // This is the expected result. 190327f905d2cb0d37c302d651d8f2b17ea56368467dneto DeprecatedRecorderStrategy deprecatedRecording; 191327f905d2cb0d37c302d651d8f2b17ea56368467dneto NewRecordingStrategy newRecording; 192327f905d2cb0d37c302d651d8f2b17ea56368467dneto 193327f905d2cb0d37c302d651d8f2b17ea56368467dneto golden.init(drawer.imageInfo()); 194327f905d2cb0d37c302d651d8f2b17ea56368467dneto deprecatedRecording.init(drawer.imageInfo()); 195327f905d2cb0d37c302d651d8f2b17ea56368467dneto newRecording.init(drawer.imageInfo()); 196327f905d2cb0d37c302d651d8f2b17ea56368467dneto 197327f905d2cb0d37c302d651d8f2b17ea56368467dneto#if !FINEGRAIN 198327f905d2cb0d37c302d651d8f2b17ea56368467dneto unsigned numErrors = 0; 199327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkString errors; 200327f905d2cb0d37c302d651d8f2b17ea56368467dneto#endif 201327f905d2cb0d37c302d651d8f2b17ea56368467dneto 202327f905d2cb0d37c302d651d8f2b17ea56368467dneto for (int iMode = 0; iMode < int(SkXfermode::kLastMode) ; iMode++ ) { 203327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkRect& clip = SkRect::MakeXYWH(100,0,100,100); 204327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkXfermode::Mode mode = SkXfermode::Mode(iMode); 205327f905d2cb0d37c302d651d8f2b17ea56368467dneto 206327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkBitmap& goldenBM = golden.recordAndReplay(drawer, clip, mode); 207327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkBitmap& deprecatedBM = deprecatedRecording.recordAndReplay(drawer, clip, mode); 208327f905d2cb0d37c302d651d8f2b17ea56368467dneto const SkBitmap& newRecordingBM = newRecording.recordAndReplay(drawer, clip, mode); 209327f905d2cb0d37c302d651d8f2b17ea56368467dneto 210327f905d2cb0d37c302d651d8f2b17ea56368467dneto size_t pixelsSize = goldenBM.getSize(); 211327f905d2cb0d37c302d651d8f2b17ea56368467dneto REPORTER_ASSERT( reporter, pixelsSize == deprecatedBM.getSize() ); 212327f905d2cb0d37c302d651d8f2b17ea56368467dneto REPORTER_ASSERT( reporter, pixelsSize == newRecordingBM.getSize() ); 213327f905d2cb0d37c302d651d8f2b17ea56368467dneto 214327f905d2cb0d37c302d651d8f2b17ea56368467dneto // The pixel arrays should match. 215327f905d2cb0d37c302d651d8f2b17ea56368467dneto#if FINEGRAIN 216327f905d2cb0d37c302d651d8f2b17ea56368467dneto REPORTER_ASSERT_MESSAGE( reporter, 217327f905d2cb0d37c302d651d8f2b17ea56368467dneto 0==memcmp( goldenBM.getPixels(), deprecatedBM.getPixels(), pixelsSize ), 218327f905d2cb0d37c302d651d8f2b17ea56368467dneto "Tiled bitmap is wrong"); 219327f905d2cb0d37c302d651d8f2b17ea56368467dneto REPORTER_ASSERT_MESSAGE( reporter, 220327f905d2cb0d37c302d651d8f2b17ea56368467dneto 0==memcmp( goldenBM.getPixels(), recordingBM.getPixels(), pixelsSize ), 221327f905d2cb0d37c302d651d8f2b17ea56368467dneto "SkRecorder bitmap is wrong"); 222327f905d2cb0d37c302d651d8f2b17ea56368467dneto#else 223327f905d2cb0d37c302d651d8f2b17ea56368467dneto if ( memcmp( goldenBM.getPixels(), deprecatedBM.getPixels(), pixelsSize ) ) { 224327f905d2cb0d37c302d651d8f2b17ea56368467dneto numErrors++; 225327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkString str; 226327f905d2cb0d37c302d651d8f2b17ea56368467dneto str.printf("For SkXfermode %d %s: Deprecated recorder bitmap is wrong\n", iMode, SkXfermode::ModeName(mode)); 227327f905d2cb0d37c302d651d8f2b17ea56368467dneto errors.append(str); 228327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 229327f905d2cb0d37c302d651d8f2b17ea56368467dneto if ( memcmp( goldenBM.getPixels(), newRecordingBM.getPixels(), pixelsSize ) ) { 230327f905d2cb0d37c302d651d8f2b17ea56368467dneto numErrors++; 231327f905d2cb0d37c302d651d8f2b17ea56368467dneto SkString str; 232327f905d2cb0d37c302d651d8f2b17ea56368467dneto str.printf("For SkXfermode %d %s: SkPictureRecorder bitmap is wrong\n", iMode, SkXfermode::ModeName(mode)); 233327f905d2cb0d37c302d651d8f2b17ea56368467dneto errors.append(str); 234327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 235327f905d2cb0d37c302d651d8f2b17ea56368467dneto#endif 236327f905d2cb0d37c302d651d8f2b17ea56368467dneto } 237327f905d2cb0d37c302d651d8f2b17ea56368467dneto#if !FINEGRAIN 238327f905d2cb0d37c302d651d8f2b17ea56368467dneto REPORTER_ASSERT_MESSAGE( reporter, 0==numErrors, errors.c_str() ); 239327f905d2cb0d37c302d651d8f2b17ea56368467dneto#endif 240327f905d2cb0d37c302d651d8f2b17ea56368467dneto} 241