Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Unified Diff: gm/optimizations.cpp

Issue 12843028: Add testing of optimizations to GM (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | gyp/SampleApp.gyp » ('j') | include/core/SkPicture.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gm/optimizations.cpp
===================================================================
--- gm/optimizations.cpp (revision 0)
+++ gm/optimizations.cpp (revision 0)
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "..\debugger\SkDebugCanvas.h"
+#include "SkPictureFlat.h"
+
+namespace {
+
+// Do the commands in 'input' match the supplied pattern? Note: this is a pretty
+// heavy-weight operation since we are drawing the picture into a debug canvas
+// to extract the commands.
+bool check_pattern(SkPicture& input, const SkTDArray<DrawType> &pattern) {
+ SkDebugCanvas debugCanvas(input.width(), input.height());
+ debugCanvas.setBounds(input.width(), input.height());
+ input.draw(&debugCanvas);
+
+ if (pattern.count() != debugCanvas.getSize()) {
+ return false;
+ }
+
+ for (int i = 0; i < pattern.count(); ++i) {
+ if (pattern[i] != debugCanvas.getDrawCommandAt(i)->getType()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// construct the pattern removed by the SkPictureRecord::remove_save_layer1
+// optimization, i.e.:
+// SAVE_LAYER
+// DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT
+// RESTORE
+SkPicture* create_save_layer_opt_1(SkTDArray<DrawType> *preOptPattern,
+ SkTDArray<DrawType> *postOptPattern,
+ const SkBitmap& checkerBoard) {
+ // Create the pattern that should trigger the optimization
+ preOptPattern->setCount(5);
+ (*preOptPattern)[0] = SAVE;
+ (*preOptPattern)[1] = SAVE_LAYER;
+ (*preOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT;
+ (*preOptPattern)[3] = RESTORE;
+ (*preOptPattern)[4] = RESTORE;
+
+ // Create the pattern that should appear after the optimization
+ postOptPattern->setCount(5);
+ (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
+ (*postOptPattern)[1] = SAVE;
+ (*postOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT;
+ (*postOptPattern)[3] = RESTORE;
+ (*postOptPattern)[4] = RESTORE;
+
+ SkPicture* result = new SkPicture;
+
+ // have to disable the optimizations while generating the picture
+ SkCanvas* canvas = result->beginRecording(100, 100,
+ SkPicture::kDisableOptimizations_RecordingFlag);
+
+ SkPaint saveLayerPaint;
+ saveLayerPaint.setColor(0xCC000000);
+
+ // saveLayer's 'bounds' parameter must be NULL for this optimization
+ canvas->saveLayer(NULL, &saveLayerPaint);
+
+ SkRect rect = { 10, 10, 90, 90 };
+
+ // The dbmr2r's paint must be opaque
+ SkPaint dbmr2rPaint;
+ dbmr2rPaint.setColor(0xFF000000);
+
+ canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, &dbmr2rPaint);
+ canvas->restore();
+
+ result->endRecording();
+
+ return result;
+}
+
+// construct the pattern removed by the SkPictureRecord::remove_save_layer2
+// optimization, i.e.:
+// SAVE_LAYER (with NULL == bounds)
+// SAVE
+// CLIP_RECT
+// DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT
+// RESTORE
+// RESTORE
+SkPicture* create_save_layer_opt_2(SkTDArray<DrawType> *preOptPattern,
+ SkTDArray<DrawType> *postOptPattern,
+ const SkBitmap& checkerBoard) {
+ // Create the pattern that should trigger the optimization
+ preOptPattern->setCount(8);
+ (*preOptPattern)[0] = SAVE;
+ (*preOptPattern)[1] = SAVE_LAYER;
+ (*preOptPattern)[2] = SAVE;
+ (*preOptPattern)[3] = CLIP_RECT;
+ (*preOptPattern)[4] = DRAW_BITMAP_RECT_TO_RECT;
+ (*preOptPattern)[5] = RESTORE;
+ (*preOptPattern)[6] = RESTORE;
+ (*preOptPattern)[7] = RESTORE;
+
+ // Create the pattern that should appear after the optimization
+ postOptPattern->setCount(8);
+ (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
+ (*postOptPattern)[1] = SAVE;
+ (*postOptPattern)[2] = SAVE;
+ (*postOptPattern)[3] = CLIP_RECT;
+ (*postOptPattern)[4] = DRAW_BITMAP_RECT_TO_RECT;
+ (*postOptPattern)[5] = RESTORE;
+ (*postOptPattern)[6] = RESTORE;
+ (*postOptPattern)[7] = RESTORE;
+
+ SkPicture* result = new SkPicture;
+
+ // have to disable the optimizations while generating the picture
+ SkCanvas* canvas = result->beginRecording(100, 100,
+ SkPicture::kDisableOptimizations_RecordingFlag);
+
+ SkPaint saveLayerPaint;
+ saveLayerPaint.setColor(0xCC000000);
+
+ // saveLayer's 'bounds' parameter must be NULL for this optimization
+ canvas->saveLayer(NULL, &saveLayerPaint);
+
+ canvas->save();
+
+ SkRect rect = { 10, 10, 90, 90 };
+ canvas->clipRect(rect);
+
+ // The dbmr2r's paint must be opaque
+ SkPaint dbmr2rPaint;
+ dbmr2rPaint.setColor(0xFF000000);
+
+ canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, &dbmr2rPaint);
+ canvas->restore();
+ canvas->restore();
+
+ result->endRecording();
+
+ return result;
+}
+
+};
+
+
+// As our .skp optimizations get folded into the captured skps our code will
+// no longer be locally exercised. This GM manually constructs the patterns
+// our optimizations will remove to test them. It acts as both a GM and a unit
+// test
+class OptimizationsGM : public skiagm::GM {
+public:
+ OptimizationsGM() {
+ this->makeCheckerboard();
+ }
+
+protected:
+ SkString onShortName() {
+ return SkString("optimizations");
+ }
+
+ SkISize onISize() { return SkISize::Make(800, 800); }
+
+ typedef SkPicture* (*PFCreateOpt)(SkTDArray<DrawType> *preOptPattern,
+ SkTDArray<DrawType> *postOptPattern,
+ const SkBitmap& checkerBoard);
+
+ virtual void onDraw(SkCanvas* canvas) {
+
+ PFCreateOpt gOpts[] = {
+ create_save_layer_opt_1,
+ create_save_layer_opt_2
+ };
+
+ SkTDArray<DrawType> prePattern, postPattern;
+
+ for (int i = 0; i < SK_ARRAY_COUNT(gOpts); ++i) {
+ SkAutoTUnref<SkPicture> pre((*gOpts)(&prePattern, &postPattern, fCheckerboard));
+
+ SkASSERT(check_pattern(*pre, prePattern));
+
+ canvas->drawPicture(*pre);
+
+ canvas->translate(SkIntToScalar(pre->width()), 0);
+
+ SkAutoTUnref<SkPicture> post(new SkPicture);
+
+ SkCanvas* recordCanvas = post->beginRecording(pre->width(), pre->height());
+
+ pre->draw(recordCanvas);
+
+ post->endRecording();
+
+ SkASSERT(check_pattern(*post, postPattern));
Justin Novosad 2013/03/25 18:34:55 This really feels like it should be a unit test ra
+
+ canvas->drawPicture(*post);
+
+ canvas->translate(SkIntToScalar(-pre->width()),
+ SkIntToScalar(post->height()));
+
+ // TODO: we could also render the pre and post pictures to bitmaps
+ // and manually compare them in this method
+ }
+ }
+
+private:
+ void makeCheckerboard() {
+ static const unsigned int kCheckerboardWidth = 16;
+ static const unsigned int kCheckerboardHeight = 16;
+
+ fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config,
+ kCheckerboardWidth, kCheckerboardHeight);
+ fCheckerboard.allocPixels();
+ SkAutoLockPixels lock(fCheckerboard);
+ for (int y = 0; y < kCheckerboardHeight; y += 2) {
+ SkPMColor* scanline = fCheckerboard.getAddr32(0, y);
+ for (int x = 0; x < kCheckerboardWidth; x += 2) {
+ *scanline++ = 0xFFFFFFFF;
+ *scanline++ = 0xFF000000;
+ }
+ scanline = fCheckerboard.getAddr32(0, y + 1);
+ for (int x = 0; x < kCheckerboardWidth; x += 2) {
+ *scanline++ = 0xFF000000;
+ *scanline++ = 0xFFFFFFFF;
+ }
+ }
+ }
+
+ SkBitmap fCheckerboard;
+
+ typedef skiagm::GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return new OptimizationsGM; )
Property changes on: gm\optimizations.cpp
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « no previous file | gyp/SampleApp.gyp » ('j') | include/core/SkPicture.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698