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 "SkImageDecoder.h"
|
||||||
#include "SkImageEncoder.h"
|
#include "SkImageEncoder.h"
|
||||||
#include "SkPicture.h"
|
#include "SkPicture.h"
|
||||||
#include "SkStream.h"
|
|
||||||
#include "SkRefCnt.h"
|
#include "SkRefCnt.h"
|
||||||
|
#include "SkStream.h"
|
||||||
|
#include "SamplePipeControllers.h"
|
||||||
|
|
||||||
static bool gForceBWtext;
|
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,
|
static ErrorBitfield test_pipe_playback(GM* gm,
|
||||||
const ConfigData& gRec,
|
const ConfigData& gRec,
|
||||||
const SkBitmap& comparisonBitmap,
|
const SkBitmap& comparisonBitmap,
|
||||||
@ -680,6 +642,27 @@ static ErrorBitfield test_pipe_playback(GM* gm,
|
|||||||
"-pipe", bitmap, NULL, &comparisonBitmap);
|
"-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,
|
static void write_picture_serialization(GM* gm, const ConfigData& rec,
|
||||||
const char writePicturePath[]) {
|
const char writePicturePath[]) {
|
||||||
// only do this once, so we pick raster
|
// only do this once, so we pick raster
|
||||||
@ -701,6 +684,7 @@ static void usage(const char * argv0) {
|
|||||||
SkDebugf(
|
SkDebugf(
|
||||||
"%s [-w writePath] [-r readPath] [-d diffPath] [-i resourcePath]\n"
|
"%s [-w writePath] [-r readPath] [-d diffPath] [-i resourcePath]\n"
|
||||||
" [--noreplay] [--pipe] [--serialize] [--forceBWtext] [--nopdf] \n"
|
" [--noreplay] [--pipe] [--serialize] [--forceBWtext] [--nopdf] \n"
|
||||||
|
" [--tiledPipe] \n"
|
||||||
" [--nodeferred] [--match substring] [--notexturecache]\n"
|
" [--nodeferred] [--match substring] [--notexturecache]\n"
|
||||||
, argv0);
|
, argv0);
|
||||||
SkDebugf(" writePath: directory to write rendered images in.\n");
|
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(" resourcePath: directory that stores image resources.\n");
|
||||||
SkDebugf(" --noreplay: do not exercise SkPicture replay.\n");
|
SkDebugf(" --noreplay: do not exercise SkPicture replay.\n");
|
||||||
SkDebugf(" --pipe: Exercise SkGPipe replay.\n");
|
SkDebugf(" --pipe: Exercise SkGPipe replay.\n");
|
||||||
|
SkDebugf(" --tiledPipe: Exercise tiled SkGPipe replay.\n");
|
||||||
SkDebugf(
|
SkDebugf(
|
||||||
" --serialize: exercise SkPicture serialization & deserialization.\n");
|
" --serialize: exercise SkPicture serialization & deserialization.\n");
|
||||||
SkDebugf(" --forceBWtext: disable text anti-aliasing.\n");
|
SkDebugf(" --forceBWtext: disable text anti-aliasing.\n");
|
||||||
@ -823,6 +808,7 @@ int main(int argc, char * const argv[]) {
|
|||||||
bool doPDF = true;
|
bool doPDF = true;
|
||||||
bool doReplay = true;
|
bool doReplay = true;
|
||||||
bool doPipe = false;
|
bool doPipe = false;
|
||||||
|
bool doTiledPipe = false;
|
||||||
bool doSerialize = false;
|
bool doSerialize = false;
|
||||||
bool doDeferred = true;
|
bool doDeferred = true;
|
||||||
bool disableTextureCache = false;
|
bool disableTextureCache = false;
|
||||||
@ -861,6 +847,8 @@ int main(int argc, char * const argv[]) {
|
|||||||
gForceBWtext = true;
|
gForceBWtext = true;
|
||||||
} else if (strcmp(*argv, "--pipe") == 0) {
|
} else if (strcmp(*argv, "--pipe") == 0) {
|
||||||
doPipe = true;
|
doPipe = true;
|
||||||
|
} else if (strcmp(*argv, "--tiledPipe") == 0) {
|
||||||
|
doTiledPipe = true;
|
||||||
} else if (strcmp(*argv, "--noreplay") == 0) {
|
} else if (strcmp(*argv, "--noreplay") == 0) {
|
||||||
doReplay = false;
|
doReplay = false;
|
||||||
} else if (strcmp(*argv, "--nopdf") == 0) {
|
} else if (strcmp(*argv, "--nopdf") == 0) {
|
||||||
@ -1007,6 +995,13 @@ int main(int argc, char * const argv[]) {
|
|||||||
readPath, diffPath);
|
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 &&
|
if ((ERROR_NONE == testErrors) && doSerialize &&
|
||||||
!(gmFlags & GM::kSkipPicture_Flag)) {
|
!(gmFlags & GM::kSkipPicture_Flag)) {
|
||||||
testErrors |= test_picture_serialization(gm, gRec[i],
|
testErrors |= test_picture_serialization(gm, gRec[i],
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
'../gm/gm.cpp',
|
'../gm/gm.cpp',
|
||||||
'../gm/gmmain.cpp',
|
'../gm/gmmain.cpp',
|
||||||
'../gm/system_preferences_default.cpp',
|
'../gm/system_preferences_default.cpp',
|
||||||
|
'../src/pipe/utils/SamplePipeControllers.h',
|
||||||
|
'../src/pipe/utils/SamplePipeControllers.cpp',
|
||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'core.gyp:core',
|
'core.gyp:core',
|
||||||
|
@ -23,6 +23,7 @@ class SkCanvas;
|
|||||||
|
|
||||||
class SkGPipeReader {
|
class SkGPipeReader {
|
||||||
public:
|
public:
|
||||||
|
SkGPipeReader();
|
||||||
SkGPipeReader(SkCanvas* target);
|
SkGPipeReader(SkCanvas* target);
|
||||||
~SkGPipeReader();
|
~SkGPipeReader();
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ public:
|
|||||||
kReadAtom_Status//!< finished reading an atom
|
kReadAtom_Status//!< finished reading an atom
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void setCanvas(SkCanvas*);
|
||||||
// data must be 4-byte aligned
|
// data must be 4-byte aligned
|
||||||
// length must be a multiple of 4
|
// length must be a multiple of 4
|
||||||
Status playback(const void* data, size_t length, size_t* bytesRead = NULL,
|
Status playback(const void* data, size_t length, size_t* bytesRead = NULL,
|
||||||
|
@ -545,12 +545,21 @@ SkGPipeState::~SkGPipeState() {
|
|||||||
|
|
||||||
#include "SkGPipe.h"
|
#include "SkGPipe.h"
|
||||||
|
|
||||||
SkGPipeReader::SkGPipeReader(SkCanvas* target) {
|
SkGPipeReader::SkGPipeReader() {
|
||||||
SkSafeRef(target);
|
fCanvas = NULL;
|
||||||
fCanvas = target;
|
|
||||||
fState = 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() {
|
SkGPipeReader::~SkGPipeReader() {
|
||||||
SkSafeUnref(fCanvas);
|
SkSafeUnref(fCanvas);
|
||||||
delete fState;
|
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