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

Unified Diff: tests/DeferredCanvasTest.cpp

Issue 933043006: Implement SkBaseDevice snapshot support Base URL: https://skia.googlesource.com/skia.git@skimage-filters-04-snapshot-devices
Patch Set: Created 5 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 | « src/utils/SkDeferredCanvas.cpp ('k') | tests/SurfaceTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/DeferredCanvasTest.cpp
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index a5ef714fedc07a22508dbafdd9503caabdd238f6..5a7813a3a1b5fb94f321798ba0e5a8595a0affcd 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -48,16 +48,31 @@ static SkPMColor read_pixel(SkSurface* surface, int x, int y) {
surface->draw(&canvas, -SkIntToScalar(x), -SkIntToScalar(y), &paint);
return pixel;
}
+class MockSurface;
+class MockDevice : public SkBitmapDevice {
+public:
+ MockDevice(MockSurface* surface, const SkBitmap& bm) : SkBitmapDevice(bm), fSurface(surface) {
+ }
+ void discard() SK_OVERRIDE;
+ private:
+ MockSurface* fSurface;
+ typedef SkBitmapDevice INHERITED;
+};
class MockSurface : public SkSurface_Base {
public:
MockSurface(int width, int height) : SkSurface_Base(width, height, NULL) {
clearCounts();
- fBitmap.allocN32Pixels(width, height);
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(width, height);
+ fDevice.reset(SkNEW_ARGS(MockDevice, (this, bitmap)));
+ fDeviceGenerationID = fDevice->accessBitmap(false).getGenerationID();
+ fGenerationID = this->newGenerationID();
}
SkCanvas* onNewCanvas() SK_OVERRIDE {
- return SkNEW_ARGS(SkCanvas, (fBitmap));
+ return SkNEW_ARGS(SkCanvas, (fDevice));
}
SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE {
@@ -65,33 +80,40 @@ public:
}
SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE {
- return SkNewImageFromBitmap(fBitmap, &this->props());
+ return fDevice->newImageSnapshot();
}
- void onCopyOnWrite(ContentChangeMode mode) SK_OVERRIDE {
- if (mode == SkSurface::kDiscard_ContentChangeMode) {
- fCOWDiscardCount++;
- } else {
- fCOWRetainCount++;
+ uint32_t generationID() SK_OVERRIDE {
+ uint32_t deviceGenerationID = fDevice->accessBitmap(false).getGenerationID();
+ if (fDeviceGenerationID != deviceGenerationID) {
+ fDeviceGenerationID = deviceGenerationID;
+ fGenerationID = this->newGenerationID();
}
+ return fGenerationID;
}
- void onDiscard() SK_OVERRIDE {
+ void incDiscardCount() {
fDiscardCount++;
}
void clearCounts() {
- fCOWDiscardCount = 0;
- fCOWRetainCount = 0;
fDiscardCount = 0;
}
- int fCOWDiscardCount;
- int fCOWRetainCount;
+ SkAutoTUnref<MockDevice> fDevice;
+ uint32_t fDeviceGenerationID;
+ uint32_t fGenerationID;
+
int fDiscardCount;
- SkBitmap fBitmap;
};
+void MockDevice::discard() {
+ if (fSurface) {
+ fSurface->incDiscardCount();
+ }
+ this->INHERITED::discard();
+}
+
static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter) {
SkAutoTUnref<MockSurface> surface(SkNEW_ARGS(MockSurface, (10, 10)));
SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
@@ -101,174 +123,174 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
srcBitmap.eraseColor(SK_ColorGREEN);
// Tests below depend on this bitmap being recognized as opaque
- // Preliminary sanity check: no copy on write if no active snapshot
- // Discard notification happens on SkSurface::onDiscard, since no
- // active snapshot.
+
+ // Case 0: SkBaseDevice::discard is called even when clear is the first command.
+ // The call is made only after flush.
+ uint32_t surfaceID = surface->generationID();
surface->clearCounts();
canvas->clear(SK_ColorWHITE);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
- // Case 1: Discard notification happens upon flushing
+ // Case 1: SkBaseDevice::discard is called upon flushing
// with an Image attached.
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->clear(SK_ColorWHITE);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 1 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
- REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
// Case 2: Opaque writePixels
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 3: writePixels that partially covers the canvas
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image3(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 4: unpremultiplied opaque writePixels that entirely
// covers the canvas
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image4(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->writePixels(srcBitmap, 0, 0);
- REPORTER_ASSERT(reporter, 1 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
- REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 5: unpremultiplied opaque writePixels that partially
- // covers the canvas
+ // covers the canvas. The surface changes immediately.
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image5(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->writePixels(srcBitmap, 5, 0);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 1 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 6: unpremultiplied opaque writePixels that entirely
- // covers the canvas, preceded by clear
+ // covers the canvas, preceded by clear.
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image6(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->clear(SK_ColorWHITE);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->writePixels(srcBitmap, 0, 0);
- REPORTER_ASSERT(reporter, 1 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
- REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 7: unpremultiplied opaque writePixels that partially
// covers the canvas, preceeded by a clear
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image7(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->clear(SK_ColorWHITE);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->writePixels(srcBitmap, 5, 0);
- REPORTER_ASSERT(reporter, 1 == surface->fCOWDiscardCount); // because of the clear
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
- REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); // because of the clear
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
// Case 8: unpremultiplied opaque writePixels that partially
// covers the canvas, preceeded by a drawREct that partially
// covers the canvas
+ surfaceID = surface->generationID();
surface->clearCounts();
SkAutoTUnref<SkImage> image8(canvas->newImageSnapshot());
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
SkPaint paint;
canvas->drawRect(SkRect::MakeLTRB(0, 0, 5, 5), paint);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->writePixels(srcBitmap, 5, 0);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 1 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID != surface->generationID());
+ surfaceID = surface->generationID();
surface->clearCounts();
canvas->flush();
- REPORTER_ASSERT(reporter, 0 == surface->fCOWDiscardCount);
- REPORTER_ASSERT(reporter, 0 == surface->fCOWRetainCount);
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
+ REPORTER_ASSERT(reporter, surfaceID == surface->generationID());
}
static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) {
@@ -440,19 +462,6 @@ static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
}
}
-class MockDevice : public SkBitmapDevice {
-public:
- MockDevice(const SkBitmap& bm) : SkBitmapDevice(bm) {
- fDrawBitmapCallCount = 0;
- }
- virtual void drawBitmap(const SkDraw&, const SkBitmap&,
- const SkMatrix&, const SkPaint&) SK_OVERRIDE {
- fDrawBitmapCallCount++;
- }
-
- int fDrawBitmapCallCount;
-};
-
class NotificationCounter : public SkDeferredCanvas::NotificationClient {
public:
NotificationCounter() {
@@ -689,22 +698,6 @@ static void TestDeferredCanvasBitmapSizeThreshold(skiatest::Reporter* reporter)
}
}
-
-typedef const void* PixelPtr;
-// Returns an opaque pointer which, either points to a GrTexture or RAM pixel
-// buffer. Used to test pointer equality do determine whether a surface points
-// to the same pixel data storage as before.
-static PixelPtr get_surface_ptr(SkSurface* surface, bool useGpu) {
-#if SK_SUPPORT_GPU
- if (useGpu) {
- return surface->getCanvas()->internal_private_accessTopLayerRenderTarget()->asTexture();
- } else
-#endif
- {
- return surface->peekPixels(NULL, NULL);
- }
-}
-
static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10);
bool useGpu = SkToBool(factory);
@@ -745,10 +738,10 @@ static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFac
SkImage* image1 = canvas->newImageSnapshot();
SkAutoTUnref<SkImage> aur_i1(image1);
- PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
- // The following clear would normally trigger a copy on write, but
+ // The following clear would normally trigger a surface modification, but
// it won't because rendering is deferred.
canvas->clear(SK_ColorBLACK);
+ uint32_t genid1 = surface->generationID();
// Obtaining a snapshot directly from the surface (as opposed to the
// SkDeferredCanvas) will not trigger a flush of deferred draw operations
// and will therefore return the same image as the previous snapshot.
@@ -756,34 +749,26 @@ static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFac
SkAutoTUnref<SkImage> aur_i2(image2);
// Images identical because of deferral
REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID());
+ uint32_t genid2 = surface->generationID();
// Now we obtain a snpshot via the deferred canvas, which triggers a flush.
// Because there is a pending clear, this will generate a different image.
SkImage* image3 = canvas->newImageSnapshot();
SkAutoTUnref<SkImage> aur_i3(image3);
REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID());
- // Verify that backing store is now a different buffer because of copy on
- // write
- PixelPtr pixels2 = get_surface_ptr(surface, useGpu);
- REPORTER_ASSERT(reporter, pixels1 != pixels2);
- // Verify copy-on write with a draw operation that gets deferred by
+ // Verify that backing store is now a different buffer because of changed
+ // surface generation id.
+ uint32_t genid3 = surface->generationID();
+ REPORTER_ASSERT(reporter, genid1 == genid2);
+ REPORTER_ASSERT(reporter, genid1 != genid3);
+ // Verify surface modification with a draw operation that gets deferred by
// the in order draw buffer.
SkPaint paint;
canvas->drawPaint(paint);
SkImage* image4 = canvas->newImageSnapshot(); // implicit flush
SkAutoTUnref<SkImage> aur_i4(image4);
- REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID());
- PixelPtr pixels3 = get_surface_ptr(surface, useGpu);
- REPORTER_ASSERT(reporter, pixels2 != pixels3);
- // Verify that a direct canvas flush with a pending draw does not trigger
- // a copy on write when the surface is not sharing its buffer with an
- // SkImage.
- canvas->clear(SK_ColorWHITE);
- canvas->flush();
- PixelPtr pixels4 = get_surface_ptr(surface, useGpu);
- canvas->drawPaint(paint);
- canvas->flush();
- PixelPtr pixels5 = get_surface_ptr(surface, useGpu);
- REPORTER_ASSERT(reporter, pixels4 == pixels5);
+ REPORTER_ASSERT(reporter, image3->uniqueID() != image4->uniqueID());
+ uint32_t genid4 = surface->generationID();
+ REPORTER_ASSERT(reporter, genid3 != genid4);
}
}
@@ -829,21 +814,21 @@ static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
SkASSERT(alternateSurface);
SkAutoTUnref<SkSurface> aur1(surface);
SkAutoTUnref<SkSurface> aur2(alternateSurface);
- PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
- PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu);
+ uint32_t genid1 = surface->generationID();
+ uint32_t genid2 = alternateSurface->generationID();
SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
canvas->setSurface(alternateSurface);
SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID());
- // Verify that none of the above operations triggered a surface copy on write.
- REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
- REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) == pixels2);
- // Verify that a flushed draw command will trigger a copy on write on alternateSurface.
+ // Verify that none of the above operations triggered a surface modification.
+ REPORTER_ASSERT(reporter, surface->generationID() == genid1);
+ REPORTER_ASSERT(reporter, alternateSurface->generationID() == genid2);
+ // Verify that a flushed draw command will trigger a modification on alternateSurface.
canvas->clear(SK_ColorWHITE);
canvas->flush();
- REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
- REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != pixels2);
+ REPORTER_ASSERT(reporter, surface->generationID() == genid1);
+ REPORTER_ASSERT(reporter, alternateSurface->generationID() != genid2);
}
}
« no previous file with comments | « src/utils/SkDeferredCanvas.cpp ('k') | tests/SurfaceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698