Add tiled rendering as an option to GM.
Use an SkGPipe to play back drawing into tiles. This will help us to debug differences in drawing while tiled. Pass --tiledPipe to gm to use the tiled pipe. Review URL: https://codereview.appspot.com/6295050 git-svn-id: http://skia.googlecode.com/svn/trunk@4199 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
47059542e7
commit
72c9672ce2
@ -20,8 +20,9 @@
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkImageEncoder.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkStream.h"
|
||||
#include "SamplePipeControllers.h"
|
||||
|
||||
static bool gForceBWtext;
|
||||
|
||||
@ -619,45 +620,6 @@ static ErrorBitfield test_picture_serialization(GM* gm,
|
||||
}
|
||||
}
|
||||
|
||||
class PipeController : public SkGPipeController {
|
||||
public:
|
||||
PipeController(SkCanvas* target);
|
||||
~PipeController();
|
||||
virtual void* requestBlock(size_t minRequest, size_t* actual);
|
||||
virtual void notifyWritten(size_t bytes);
|
||||
private:
|
||||
SkGPipeReader fReader;
|
||||
void* fBlock;
|
||||
size_t fBlockSize;
|
||||
size_t fBytesWritten;
|
||||
SkGPipeReader::Status fStatus;
|
||||
};
|
||||
|
||||
PipeController::PipeController(SkCanvas* target)
|
||||
:fReader(target) {
|
||||
fBlock = NULL;
|
||||
fBlockSize = fBytesWritten = 0;
|
||||
}
|
||||
|
||||
PipeController::~PipeController() {
|
||||
sk_free(fBlock);
|
||||
}
|
||||
|
||||
void* PipeController::requestBlock(size_t minRequest, size_t *actual) {
|
||||
sk_free(fBlock);
|
||||
fBlockSize = minRequest * 4;
|
||||
fBlock = sk_malloc_throw(fBlockSize);
|
||||
fBytesWritten = 0;
|
||||
*actual = fBlockSize;
|
||||
return fBlock;
|
||||
}
|
||||
|
||||
void PipeController::notifyWritten(size_t bytes) {
|
||||
fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes);
|
||||
SkASSERT(SkGPipeReader::kError_Status != fStatus);
|
||||
fBytesWritten += bytes;
|
||||
}
|
||||
|
||||
static ErrorBitfield test_pipe_playback(GM* gm,
|
||||
const ConfigData& gRec,
|
||||
const SkBitmap& comparisonBitmap,
|
||||
@ -680,6 +642,27 @@ static ErrorBitfield test_pipe_playback(GM* gm,
|
||||
"-pipe", bitmap, NULL, &comparisonBitmap);
|
||||
}
|
||||
|
||||
static ErrorBitfield test_tiled_pipe_playback(GM* gm,
|
||||
const ConfigData& gRec,
|
||||
const SkBitmap& comparisonBitmap,
|
||||
const char readPath [],
|
||||
const char diffPath []) {
|
||||
if (kRaster_Backend != gRec.fBackend) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
SkBitmap bitmap;
|
||||
SkISize size = gm->getISize();
|
||||
setup_bitmap(gRec, size, &bitmap);
|
||||
TiledPipeController pipeController(bitmap);
|
||||
SkGPipeWriter writer;
|
||||
SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
|
||||
SkGPipeWriter::kCrossProcess_Flag);
|
||||
invokeGM(gm, pipeCanvas);
|
||||
writer.endRecording();
|
||||
return handle_test_results(gm, gRec, NULL, NULL, diffPath,
|
||||
"-tiled pipe", bitmap, NULL, &comparisonBitmap);
|
||||
}
|
||||
|
||||
static void write_picture_serialization(GM* gm, const ConfigData& rec,
|
||||
const char writePicturePath[]) {
|
||||
// only do this once, so we pick raster
|
||||
@ -701,6 +684,7 @@ static void usage(const char * argv0) {
|
||||
SkDebugf(
|
||||
"%s [-w writePath] [-r readPath] [-d diffPath] [-i resourcePath]\n"
|
||||
" [--noreplay] [--pipe] [--serialize] [--forceBWtext] [--nopdf] \n"
|
||||
" [--tiledPipe] \n"
|
||||
" [--nodeferred] [--match substring] [--notexturecache]\n"
|
||||
, argv0);
|
||||
SkDebugf(" writePath: directory to write rendered images in.\n");
|
||||
@ -711,6 +695,7 @@ static void usage(const char * argv0) {
|
||||
SkDebugf(" resourcePath: directory that stores image resources.\n");
|
||||
SkDebugf(" --noreplay: do not exercise SkPicture replay.\n");
|
||||
SkDebugf(" --pipe: Exercise SkGPipe replay.\n");
|
||||
SkDebugf(" --tiledPipe: Exercise tiled SkGPipe replay.\n");
|
||||
SkDebugf(
|
||||
" --serialize: exercise SkPicture serialization & deserialization.\n");
|
||||
SkDebugf(" --forceBWtext: disable text anti-aliasing.\n");
|
||||
@ -823,6 +808,7 @@ int main(int argc, char * const argv[]) {
|
||||
bool doPDF = true;
|
||||
bool doReplay = true;
|
||||
bool doPipe = false;
|
||||
bool doTiledPipe = false;
|
||||
bool doSerialize = false;
|
||||
bool doDeferred = true;
|
||||
bool disableTextureCache = false;
|
||||
@ -861,6 +847,8 @@ int main(int argc, char * const argv[]) {
|
||||
gForceBWtext = true;
|
||||
} else if (strcmp(*argv, "--pipe") == 0) {
|
||||
doPipe = true;
|
||||
} else if (strcmp(*argv, "--tiledPipe") == 0) {
|
||||
doTiledPipe = true;
|
||||
} else if (strcmp(*argv, "--noreplay") == 0) {
|
||||
doReplay = false;
|
||||
} else if (strcmp(*argv, "--nopdf") == 0) {
|
||||
@ -1007,6 +995,13 @@ int main(int argc, char * const argv[]) {
|
||||
readPath, diffPath);
|
||||
}
|
||||
|
||||
if ((ERROR_NONE == testErrors) && doTiledPipe &&
|
||||
!(gmFlags & GM::kSkipPipe_Flag)) {
|
||||
testErrors |= test_tiled_pipe_playback(gm, gRec[i],
|
||||
forwardRenderedBitmap,
|
||||
readPath, diffPath);
|
||||
}
|
||||
|
||||
if ((ERROR_NONE == testErrors) && doSerialize &&
|
||||
!(gmFlags & GM::kSkipPicture_Flag)) {
|
||||
testErrors |= test_picture_serialization(gm, gRec[i],
|
||||
|
@ -17,6 +17,8 @@
|
||||
'../gm/gm.cpp',
|
||||
'../gm/gmmain.cpp',
|
||||
'../gm/system_preferences_default.cpp',
|
||||
'../src/pipe/utils/SamplePipeControllers.h',
|
||||
'../src/pipe/utils/SamplePipeControllers.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'core.gyp:core',
|
||||
|
@ -23,6 +23,7 @@ class SkCanvas;
|
||||
|
||||
class SkGPipeReader {
|
||||
public:
|
||||
SkGPipeReader();
|
||||
SkGPipeReader(SkCanvas* target);
|
||||
~SkGPipeReader();
|
||||
|
||||
@ -33,6 +34,7 @@ public:
|
||||
kReadAtom_Status//!< finished reading an atom
|
||||
};
|
||||
|
||||
void setCanvas(SkCanvas*);
|
||||
// data must be 4-byte aligned
|
||||
// length must be a multiple of 4
|
||||
Status playback(const void* data, size_t length, size_t* bytesRead = NULL,
|
||||
|
@ -545,12 +545,21 @@ SkGPipeState::~SkGPipeState() {
|
||||
|
||||
#include "SkGPipe.h"
|
||||
|
||||
SkGPipeReader::SkGPipeReader(SkCanvas* target) {
|
||||
SkSafeRef(target);
|
||||
fCanvas = target;
|
||||
SkGPipeReader::SkGPipeReader() {
|
||||
fCanvas = NULL;
|
||||
fState = NULL;
|
||||
}
|
||||
|
||||
SkGPipeReader::SkGPipeReader(SkCanvas* target) {
|
||||
fCanvas = NULL;
|
||||
this->setCanvas(target);
|
||||
fState = NULL;
|
||||
}
|
||||
|
||||
void SkGPipeReader::setCanvas(SkCanvas *target) {
|
||||
SkRefCnt_SafeAssign(fCanvas, target);
|
||||
}
|
||||
|
||||
SkGPipeReader::~SkGPipeReader() {
|
||||
SkSafeUnref(fCanvas);
|
||||
delete fState;
|
||||
|
72
src/pipe/utils/SamplePipeControllers.cpp
Normal file
72
src/pipe/utils/SamplePipeControllers.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SamplePipeControllers.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkGPipe.h"
|
||||
|
||||
PipeController::PipeController(SkCanvas* target)
|
||||
:fReader(target) {
|
||||
fBlock = NULL;
|
||||
fBlockSize = fBytesWritten = 0;
|
||||
}
|
||||
|
||||
PipeController::~PipeController() {
|
||||
sk_free(fBlock);
|
||||
}
|
||||
|
||||
void* PipeController::requestBlock(size_t minRequest, size_t *actual) {
|
||||
sk_free(fBlock);
|
||||
fBlockSize = minRequest * 4;
|
||||
fBlock = sk_malloc_throw(fBlockSize);
|
||||
fBytesWritten = 0;
|
||||
*actual = fBlockSize;
|
||||
return fBlock;
|
||||
}
|
||||
|
||||
void PipeController::notifyWritten(size_t bytes) {
|
||||
fStatus = fReader.playback(this->getData(), bytes);
|
||||
SkASSERT(SkGPipeReader::kError_Status != fStatus);
|
||||
fBytesWritten += bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TiledPipeController::TiledPipeController(const SkBitmap& bitmap)
|
||||
: INHERITED(NULL) {
|
||||
int32_t top = 0;
|
||||
int32_t bottom;
|
||||
int32_t height = bitmap.height() / NumberOfTiles;
|
||||
SkIRect rect;
|
||||
for (int i = 0; i < NumberOfTiles; i++) {
|
||||
bottom = i + 1 == NumberOfTiles ? bitmap.height() : top + height;
|
||||
rect.setLTRB(0, top, bitmap.width(), bottom);
|
||||
top = bottom;
|
||||
|
||||
bool extracted = bitmap.extractSubset(&fBitmaps[i], rect);
|
||||
SkASSERT(extracted);
|
||||
SkDevice* device = new SkDevice(fBitmaps[i]);
|
||||
SkCanvas* canvas = new SkCanvas(device);
|
||||
device->unref();
|
||||
canvas->translate(SkIntToScalar(-rect.left()),
|
||||
SkIntToScalar(-rect.top()));
|
||||
if (0 == i) {
|
||||
fReader.setCanvas(canvas);
|
||||
} else {
|
||||
fReaders[i - 1].setCanvas(canvas);
|
||||
}
|
||||
canvas->unref();
|
||||
}
|
||||
}
|
||||
|
||||
void TiledPipeController::notifyWritten(size_t bytes) {
|
||||
for (int i = 0; i < NumberOfTiles - 1; i++) {
|
||||
fReaders[i].playback(this->getData(), bytes);
|
||||
}
|
||||
this->INHERITED::notifyWritten(bytes);
|
||||
}
|
43
src/pipe/utils/SamplePipeControllers.h
Normal file
43
src/pipe/utils/SamplePipeControllers.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkGPipe.h"
|
||||
|
||||
class SkCanvas;
|
||||
|
||||
class PipeController : public SkGPipeController {
|
||||
public:
|
||||
PipeController(SkCanvas* target);
|
||||
virtual ~PipeController();
|
||||
virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
|
||||
virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
|
||||
protected:
|
||||
const void* getData() { return (const char*) fBlock + fBytesWritten; }
|
||||
SkGPipeReader fReader;
|
||||
private:
|
||||
void* fBlock;
|
||||
size_t fBlockSize;
|
||||
size_t fBytesWritten;
|
||||
SkGPipeReader::Status fStatus;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class TiledPipeController : public PipeController {
|
||||
public:
|
||||
TiledPipeController(const SkBitmap&);
|
||||
virtual ~TiledPipeController() {};
|
||||
virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
|
||||
private:
|
||||
enum {
|
||||
NumberOfTiles = 10
|
||||
};
|
||||
SkGPipeReader fReaders[NumberOfTiles - 1];
|
||||
SkBitmap fBitmaps[NumberOfTiles];
|
||||
typedef PipeController INHERITED;
|
||||
};
|
Loading…
Reference in New Issue
Block a user