aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-06 21:07:10 +0000
committerGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-06 21:07:10 +0000
commit72c9672ce274a3b6cb40800d66374edf25b157a3 (patch)
treec7b5298b2f1ece7d390b393763dc99274fad55fe
parent47059542e7aa153926377456a6c611e55c8e428c (diff)
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
-rw-r--r--gm/gmmain.cpp75
-rw-r--r--gyp/gm.gyp2
-rw-r--r--include/pipe/SkGPipe.h2
-rw-r--r--src/pipe/SkGPipeRead.cpp13
-rw-r--r--src/pipe/utils/SamplePipeControllers.cpp72
-rw-r--r--src/pipe/utils/SamplePipeControllers.h43
6 files changed, 165 insertions, 42 deletions
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 08c7c52151..34ded4af9b 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -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],
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 980c199bdc..c3f359c37e 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -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',
diff --git a/include/pipe/SkGPipe.h b/include/pipe/SkGPipe.h
index 29b058eb2d..e0b52e044b 100644
--- a/include/pipe/SkGPipe.h
+++ b/include/pipe/SkGPipe.h
@@ -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,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 976abbf10a..ddc0cc41d9 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -545,12 +545,21 @@ SkGPipeState::~SkGPipeState() {
#include "SkGPipe.h"
+SkGPipeReader::SkGPipeReader() {
+ fCanvas = NULL;
+ fState = NULL;
+}
+
SkGPipeReader::SkGPipeReader(SkCanvas* target) {
- SkSafeRef(target);
- fCanvas = target;
+ fCanvas = NULL;
+ this->setCanvas(target);
fState = NULL;
}
+void SkGPipeReader::setCanvas(SkCanvas *target) {
+ SkRefCnt_SafeAssign(fCanvas, target);
+}
+
SkGPipeReader::~SkGPipeReader() {
SkSafeUnref(fCanvas);
delete fState;
diff --git a/src/pipe/utils/SamplePipeControllers.cpp b/src/pipe/utils/SamplePipeControllers.cpp
new file mode 100644
index 0000000000..487a2b8356
--- /dev/null
+++ b/src/pipe/utils/SamplePipeControllers.cpp
@@ -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);
+}
diff --git a/src/pipe/utils/SamplePipeControllers.h b/src/pipe/utils/SamplePipeControllers.h
new file mode 100644
index 0000000000..ace6274bae
--- /dev/null
+++ b/src/pipe/utils/SamplePipeControllers.h
@@ -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;
+};