#include "SkCommandLineFlags.h"
#include "SkPicture.h"
+#include "SkRTreePicture.h"
DEFINE_bool(replay, true, "If true, run picture replay tests.");
DEFINE_bool(rtree, true, "If true, run picture replay tests with an rtree.");
{}
void ReplayTask::draw() {
- const uint32_t flags = fUseRTree ? SkPicture::kOptimizeForClippedPlayback_RecordingFlag : 0;
- SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get(), flags));
+ SkAutoTUnref<SkPictureFactory> factory;
+ if (fUseRTree) {
+ factory.reset(SkNEW(SkRTreePictureFactory));
+ }
+ SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get(), 0, factory));
SkBitmap bitmap;
SetupBitmap(fReference.colorType(), fGM.get(), &bitmap);
#include "SkOSFile.h"
#include "SkPDFRasterizer.h"
#include "SkPicture.h"
+#include "SkQuadTreePicture.h"
#include "SkRefCnt.h"
+#include "SkRTreePicture.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkString.h"
kNone_BbhType,
kRTree_BbhType,
kTileGrid_BbhType,
+ kQuadTree_BbhType
};
enum ConfigFlags {
info.fOffset.setZero();
info.fTileInterval.set(16, 16);
factory.reset(SkNEW_ARGS(SkTileGridPictureFactory, (info)));
- }
- if (kNone_BbhType != bbhType) {
- recordFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
+ } else if (kQuadTree_BbhType == bbhType) {
+ factory.reset(SkNEW(SkQuadTreePictureFactory));
+ } else if (kRTree_BbhType == bbhType) {
+ factory.reset(SkNEW(SkRTreePictureFactory));
}
SkPictureRecorder recorder(factory);
SkCanvas* cv = recorder.beginRecording(width, height, recordFlags);
DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which "
"testIndex %% divisor == remainder.");
DEFINE_bool(pipe, false, "Exercise the SkGPipe replay test pass.");
+DEFINE_bool(quadtree, false, "Exercise the QuadTree variant of SkPicture test pass.");
DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report "
"any differences between those and the newly generated ones.");
DEFINE_bool(replay, false, "Exercise the SkPicture replay test pass.");
if (FLAGS_rtree) {
const char renderModeDescriptor[] = "-rtree";
- if ((gmFlags & GM::kSkipPicture_Flag) ||
- (gmFlags & GM::kSkipTiled_Flag)) {
+ if ((gmFlags & GM::kSkipPicture_Flag) || (gmFlags & GM::kSkipTiled_Flag)) {
+ gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
+ renderModeDescriptor);
+ errorsForAllModes.add(kIntentionallySkipped_ErrorType);
+ } else {
+ SkPicture* pict = gmmain.generate_new_picture(gm, kRTree_BbhType, 0);
+ SkAutoUnref aur(pict);
+ SkBitmap bitmap;
+ gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
+ errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
+ gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
+ &comparisonBitmap));
+ }
+ }
+
+ if (FLAGS_quadtree) {
+ const char renderModeDescriptor[] = "-quadtree";
+ if ((gmFlags & GM::kSkipPicture_Flag) || (gmFlags & GM::kSkipTiled_Flag)) {
gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
renderModeDescriptor);
errorsForAllModes.add(kIntentionallySkipped_ErrorType);
} else {
- SkPicture* pict = gmmain.generate_new_picture(
- gm, kRTree_BbhType, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkPicture* pict = gmmain.generate_new_picture(gm, kQuadTree_BbhType, 0);
SkAutoUnref aur(pict);
SkBitmap bitmap;
gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
'<(skia_src_path)/core/SkRRect.cpp',
'<(skia_src_path)/core/SkRTree.h',
'<(skia_src_path)/core/SkRTree.cpp',
+ '<(skia_src_path)/core/SkRTreePicture.cpp',
'<(skia_src_path)/core/SkScaledImageCache.cpp',
'<(skia_src_path)/core/SkScalar.cpp',
'<(skia_src_path)/core/SkScalerContext.cpp',
'<(skia_include_path)/core/SkRefCnt.h',
'<(skia_include_path)/core/SkRegion.h',
'<(skia_include_path)/core/SkRRect.h',
+ '<(skia_include_path)/core/SkRTreePicture.h',
'<(skia_include_path)/core/SkScalar.h',
'<(skia_include_path)/core/SkShader.h',
'<(skia_include_path)/core/SkStream.h',
'SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1',
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
'SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD',
+ 'SK_SUPPORT_DEPRECATED_RECORD_FLAGS',
'SK_SUPPORT_LEGACY_N32_NAME',
],
},
clip-query calls will reflect the path's bounds, not the actual
path.
*/
- kUsePathBoundsForClip_RecordingFlag = 0x01,
+ kUsePathBoundsForClip_RecordingFlag = 0x01
+ };
+
+#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
+ // TODO: once kOptimizeForClippedPlayback_RecordingFlag is hidden from
+ // all external consumers, SkPicture::createBBoxHierarchy can also be
+ // cleaned up.
+private:
+#endif
+ enum Deprecated_RecordingFlags {
/* This flag causes the picture to compute bounding boxes and build
up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
usually stack-based clip/etc state. This requires an increase in
*/
kOptimizeForClippedPlayback_RecordingFlag = 0x02,
};
+#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
+public:
+#endif
#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
private:
// For testing. Derived classes may instantiate an alternate
// SkBBoxHierarchy implementation
virtual SkBBoxHierarchy* createBBoxHierarchy() const;
+
private:
// An OperationList encapsulates a set of operation offsets into the picture byte
// stream along with the CTMs needed for those operation.
* Allocate a new SkPicture. Return NULL on failure.
*/
virtual SkPicture* create(int width, int height) = 0;
+
+private:
+ typedef SkRefCnt INHERITED;
};
class SK_API SkPictureRecorder : SkNoncopyable {
SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0) {
if (NULL != fFactory) {
fPicture.reset(fFactory->create(width, height));
+ recordFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
} else {
fPicture.reset(SkNEW(SkPicture));
}
--- /dev/null
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRTreePicture_DEFINED
+#define SkRTreePicture_DEFINED
+
+#include "SkPicture.h"
+
+/**
+ * Subclass of SkPicture that creates an RTree acceleration structure.
+ */
+class SkRTreePicture : public SkPicture {
+public:
+ virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE;
+
+private:
+ typedef SkPicture INHERITED;
+};
+
+class SkRTreePictureFactory : public SkPictureFactory {
+public:
+ SkRTreePictureFactory() {}
+
+ virtual SkPicture* create(int width, int height) SK_OVERRIDE {
+ return SkNEW(SkRTreePicture);
+ }
+
+private:
+ typedef SkPictureFactory INHERITED;
+};
+
+#endif
#include "SkSize.h"
/**
- * Subclass of SkPicture that override the behavior of the
- * kOptimizeForClippedPlayback_RecordingFlag by creating an SkTileGrid
- * structure rather than an R-Tree. The tile grid has lower recording
- * and playback costs, but is less effective at eliminating extraneous
+ * Subclass of SkPicture that creates an SkTileGrid. The tile grid has lower recording
+ * and playback costs then rTree, but is less effective at eliminating extraneous
* primitives for arbitrary query rectangles. It is most effective for
* tiled playback when the tile structure is known at record time.
*/
#include "SkQuadTreePicture.h"
#include "SkRandom.h"
#include "SkRegion.h"
+#include "SkRTreePicture.h"
#include "SkShader.h"
#include "SkTileGridPicture.h"
#include "SkUtils.h"
// no bbox playback necessary
return pic.detach();
case kRTree_BBoxType:
+ factory.reset(SkNEW(SkRTreePictureFactory));
break;
case kQuadTree_BBoxType:
factory.reset(SkNEW(SkQuadTreePictureFactory));
}
SkPictureRecorder recorder(factory);
- pic->draw(recorder.beginRecording(pic->width(), pic->height(),
- SkPicture::kOptimizeForClippedPlayback_RecordingFlag));
+ pic->draw(recorder.beginRecording(pic->width(), pic->height()));
return recorder.endRecording();
}
}
SkBBoxHierarchy* SkPicture::createBBoxHierarchy() const {
+ // TODO: this code is now replicated in SkRTreePicture. Once all external
+ // clients have been weaned off of kOptimizeForClippedPlayback_RecordingFlag,
+ // this code can be removed.
+
// These values were empirically determined to produce reasonable
// performance in most cases.
static const int kRTreeMinChildren = 6;
#include "SkRect.h"
/**
- * Subclass of SkPicture that override the behavior of the
- * kOptimizeForClippedPlayback_RecordingFlag by creating an SkQuadGrid
- * structure rather than an R-Tree. The quad tree has generally faster
+ * Subclass of SkPicture that creates an SkQuadGrid
+ * structure. The quad tree has generally faster
* tree creation time, but slightly slower query times, as compared to
* R-Tree, so some cases may be faster and some cases slower.
*/
};
class SkQuadTreePictureFactory : public SkPictureFactory {
-private:
+public:
+ SkQuadTreePictureFactory() {}
+
virtual SkPicture* create(int width, int height) SK_OVERRIDE {
return SkNEW_ARGS(SkQuadTreePicture, (SkIRect::MakeWH(width, height)));
}
--- /dev/null
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkRTreePicture.h"
+
+#include "SkRTree.h"
+
+
+SkBBoxHierarchy* SkRTreePicture::createBBoxHierarchy() const {
+ // These values were empirically determined to produce reasonable
+ // performance in most cases.
+ static const int kRTreeMinChildren = 6;
+ static const int kRTreeMaxChildren = 11;
+
+ SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
+ SkIntToScalar(fHeight));
+ bool sortDraws = false; // Do not sort draw calls when bulk loading.
+
+ return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
+ aspectRatio, sortDraws);
+}
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkPicture.h"
+#include "SkRTreePicture.h"
#include "SkRect.h"
#include "SkTileImageFilter.h"
#include "SkXfermodeImageFilter.h"
SkMatrix expectedMatrix = canvas.getTotalMatrix();
- SkPictureRecorder recorder;
- SkCanvas* recordingCanvas = recorder.beginRecording(100, 100,
- SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkAutoTUnref<SkPictureFactory> factory(SkNEW(SkRTreePictureFactory));
+ SkPictureRecorder recorder(factory);
+ SkCanvas* recordingCanvas = recorder.beginRecording(100, 100);
SkPaint paint;
SkAutoTUnref<MatrixTestImageFilter> imageFilter(
#include "SkQuadTreePicture.h"
#include "SkRRect.h"
#include "SkRandom.h"
+#include "SkRTreePicture.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTileGrid.h"
SkAutoTUnref<SkPictureFactory> factory(SkNEW_ARGS(SkTileGridPictureFactory, (gridInfo)));
SkPictureRecorder recorder(factory);
- recorder.beginRecording(1, 1, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ recorder.beginRecording(1, 1);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
canvas.drawPicture(*picture);
{
// RTree
- SkPictureRecorder recorder;
- recorder.beginRecording(1, 1, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkAutoTUnref<SkPictureFactory> factory(SkNEW(SkRTreePictureFactory));
+ SkPictureRecorder recorder(factory);
+ recorder.beginRecording(1, 1);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
canvas.drawPicture(*picture);
// quad tree
SkAutoTUnref<SkPictureFactory> factory(SkNEW(SkQuadTreePictureFactory));
SkPictureRecorder recorder(factory);
- recorder.beginRecording(1, 1, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ recorder.beginRecording(1, 1);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
canvas.drawPicture(*picture);
SkIntToScalar(1), SkIntToScalar(1));
SkAutoTUnref<SkPictureFactory> factory(SkNEW_ARGS(SkTileGridPictureFactory, (info)));
SkPictureRecorder recorder(factory);
- SkCanvas* canvas = recorder.beginRecording(20, 20, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkCanvas* canvas = recorder.beginRecording(20, 20);
SkPaint paint;
canvas->drawRect(rect1, paint);
canvas->drawRect(rect2, paint);
SkIntToScalar(1), SkIntToScalar(1));
SkAutoTUnref<SkPictureFactory> factory(SkNEW_ARGS(SkTileGridPictureFactory, (info)));
SkPictureRecorder recorder(factory);
- SkCanvas* canvas = recorder.beginRecording(20, 20, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkCanvas* canvas = recorder.beginRecording(20, 20);
SkPaint paint;
canvas->drawRect(rect1, paint);
canvas->drawRect(rect2, paint);
#include "SkPixelRef.h"
#include "SkQuadTree.h"
#include "SkQuadTreePicture.h"
-#include "SkRTree.h"
+#include "SkRTreePicture.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkString.h"
}
uint32_t PictureRenderer::recordFlags() {
- return ((kNone_BBoxHierarchyType == fBBoxHierarchyType) ? 0 :
- SkPicture::kOptimizeForClippedPlayback_RecordingFlag) |
- SkPicture::kUsePathBoundsForClip_RecordingFlag;
+ return (kNone_BBoxHierarchyType == fBBoxHierarchyType)
+ ? 0
+ : SkPicture::kUsePathBoundsForClip_RecordingFlag;
}
/**
///////////////////////////////////////////////////////////////////////////////////////////////
// SkPicture variants for each BBoxHierarchy type
-class RTreePicture : public SkPicture {
-public:
- virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE {
- static const int kRTreeMinChildren = 6;
- static const int kRTreeMaxChildren = 11;
- SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
- SkIntToScalar(fHeight));
- bool sortDraws = false;
- return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
- aspectRatio, sortDraws);
- }
-};
-
-class SkRTreePictureFactory : public SkPictureFactory {
-private:
- virtual SkPicture* create(int width, int height) SK_OVERRIDE {
- return SkNEW(RTreePicture);
- }
-
-private:
- typedef SkPictureFactory INHERITED;
-};
-
SkPictureFactory* PictureRenderer::getFactory() {
switch (fBBoxHierarchyType) {
case kNone_BBoxHierarchyType:
#include "SkPicture.h"
#include "SkQuadTreePicture.h"
#include "SkRecording.h"
+#include "SkRTreePicture.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTileGridPicture.h"
DEFINE_string(bbh, "", "Turn on the bbh and select the type, one of rtree, tilegrid, quadtree");
DEFINE_bool(skr, false, "Record SKR instead of SKP.");
-typedef SkPictureFactory* (*PictureFactory)(int* recordingFlags);
+typedef SkPictureFactory* (*PictureFactory)();
-static SkPictureFactory* vanilla_factory(int* recordingFlags) {
+static SkPictureFactory* vanilla_factory() {
return NULL;
}
-static SkPictureFactory* rtree_factory(int* recordingFlags) {
- *recordingFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
- return NULL;
+static SkPictureFactory* rtree_factory() {
+ return SkNEW(SkRTreePictureFactory);
}
-static SkPictureFactory* tilegrid_factory(int* recordingFlags) {
- *recordingFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
+static SkPictureFactory* tilegrid_factory() {
SkTileGridPicture::TileGridInfo info;
info.fTileInterval.set(FLAGS_tileGridSize, FLAGS_tileGridSize);
info.fMargin.setEmpty();
return SkNEW_ARGS(SkTileGridPictureFactory, (info));
}
-static SkPictureFactory* quadtree_factory(int* recordingFlags) {
- *recordingFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
+static SkPictureFactory* quadtree_factory() {
return SkNEW(SkQuadTreePictureFactory);
}
SkDELETE(SkRecording::Delete(recording)); // delete the SkPlayback*.
} else {
int recordingFlags = FLAGS_flags;
- SkAutoTUnref<SkPictureFactory> factory(pictureFactory(&recordingFlags));
+ SkAutoTUnref<SkPictureFactory> factory(pictureFactory());
SkPictureRecorder recorder(factory);
SkCanvas* canvas = recorder.beginRecording(width, height, recordingFlags);
if (NULL != src) {