/*
 * 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 "../src/image/SkImagePriv.h"
#include "../src/image/SkSurface_Base.h"
#include "SkBitmap.h"
#include "SkBitmapDevice.h"
#include "SkBitmapProcShader.h"
#include "SkDeferredCanvas.h"
#include "SkGradientShader.h"
#include "SkShader.h"
#include "SkSurface.h"
#include "Test.h"
#include "sk_tool_utils.h"

#if SK_SUPPORT_GPU
#include "GrContextFactory.h"
#else
class GrContextFactory;
#endif

static const int gWidth = 2;
static const int gHeight = 2;

static void create(SkBitmap* bm, SkColor color) {
    bm->allocN32Pixels(gWidth, gHeight);
    bm->eraseColor(color);
}

static SkSurface* createSurface(SkColor color) {
    SkSurface* surface = SkSurface::NewRasterPMColor(gWidth, gHeight);
    surface->getCanvas()->clear(color);
    return surface;
}

static SkPMColor read_pixel(SkSurface* surface, int x, int y) {
    SkPMColor pixel = 0;
    SkBitmap bitmap;
    bitmap.installPixels(SkImageInfo::MakeN32Premul(1, 1), &pixel, 4);
    SkCanvas canvas(bitmap);

    SkPaint paint;
    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    surface->draw(&canvas, -SkIntToScalar(x), -SkIntToScalar(y), &paint);
    return pixel;
}

class MockSurface : public SkSurface_Base {
public:
    MockSurface(int width, int height) : SkSurface_Base(width, height, NULL) {
        clearCounts();
        fBitmap.allocN32Pixels(width, height);
    }

    virtual SkCanvas* onNewCanvas() SK_OVERRIDE {
        return SkNEW_ARGS(SkCanvas, (fBitmap));
    }

    virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE {
        return NULL;
    }

    virtual SkImage* onNewImageSnapshot() SK_OVERRIDE {
        return SkNewImageFromBitmap(fBitmap, true, &this->props());
    }

    virtual void onCopyOnWrite(ContentChangeMode mode) SK_OVERRIDE {
        if (mode == SkSurface::kDiscard_ContentChangeMode) {
            fDiscardCount++;
        } else {
            fRetainCount++;
        }
    }

    void clearCounts() {
        fDiscardCount = 0;
        fRetainCount = 0;
    }

    int fDiscardCount, fRetainCount;
    SkBitmap fBitmap;
};

static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter) {
    SkAutoTUnref<MockSurface> surface(SkNEW_ARGS(MockSurface, (10, 10)));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    SkBitmap srcBitmap;
    srcBitmap.allocPixels(SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType));
    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
    surface->clearCounts();
    canvas->clear(SK_ColorWHITE);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 1: Discard notification happens upon flushing
    // with an Image attached.
    surface->clearCounts();
    SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->clear(SK_ColorWHITE);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 2: Opaque writePixels
    surface->clearCounts();
    SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 3: writePixels that partially covers the canvas
    surface->clearCounts();
    SkAutoTUnref<SkImage> image3(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 4: unpremultiplied opaque writePixels that entirely
    // covers the canvas
    surface->clearCounts();
    SkAutoTUnref<SkImage> image4(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->writePixels(srcBitmap, 0, 0);
    REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 5: unpremultiplied opaque writePixels that partially
    // covers the canvas
    surface->clearCounts();
    SkAutoTUnref<SkImage> image5(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->writePixels(srcBitmap, 5, 0);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 1 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 6: unpremultiplied opaque writePixels that entirely
    // covers the canvas, preceded by clear
    surface->clearCounts();
    SkAutoTUnref<SkImage> image6(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->clear(SK_ColorWHITE);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->writePixels(srcBitmap, 0, 0);
    REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 7: unpremultiplied opaque writePixels that partially
    // covers the canvas, preceeded by a clear
    surface->clearCounts();
    SkAutoTUnref<SkImage> image7(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->clear(SK_ColorWHITE);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->writePixels(srcBitmap, 5, 0);
    REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); // because of the clear
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    // Case 8: unpremultiplied opaque writePixels that partially
    // covers the canvas, preceeded by a drawREct that partially
    // covers the canvas
    surface->clearCounts();
    SkAutoTUnref<SkImage> image8(canvas->newImageSnapshot());
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    SkPaint paint;
    canvas->drawRect(SkRect::MakeLTRB(0, 0, 5, 5), paint);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);

    surface->clearCounts();
    canvas->writePixels(srcBitmap, 5, 0);
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 1 == surface->fRetainCount);

    surface->clearCounts();
    canvas->flush();
    REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
    REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
}

static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    canvas->clear(0x00000000);

    // verify that clear was deferred
    REPORTER_ASSERT(reporter, 0xFFFFFFFF == read_pixel(surface, 0, 0));

    canvas->flush();

    // verify that clear was executed
    REPORTER_ASSERT(reporter, 0 == read_pixel(surface, 0, 0));
}

static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
    SkRect fullRect;
    fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth),
        SkIntToScalar(gHeight));
    SkRect partialRect;
    partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0),
        SkIntToScalar(1), SkIntToScalar(1));

    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    // verify that frame is intially fresh
    REPORTER_ASSERT(reporter, canvas->isFreshFrame());
    // no clearing op since last call to isFreshFrame -> not fresh
    REPORTER_ASSERT(reporter, !canvas->isFreshFrame());

    // Verify that clear triggers a fresh frame
    canvas->clear(0x00000000);
    REPORTER_ASSERT(reporter, canvas->isFreshFrame());

    // Verify that clear with saved state triggers a fresh frame
    canvas->save();
    canvas->clear(0x00000000);
    canvas->restore();
    REPORTER_ASSERT(reporter, canvas->isFreshFrame());

    // Verify that clear within a layer does NOT trigger a fresh frame
    canvas->saveLayer(NULL, NULL);
    canvas->clear(0x00000000);
    canvas->restore();
    REPORTER_ASSERT(reporter, !canvas->isFreshFrame());

    // Verify that a clear with clipping triggers a fresh frame
    // (clear is not affected by clipping)
    canvas->save();
    canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false);
    canvas->clear(0x00000000);
    canvas->restore();
    REPORTER_ASSERT(reporter, canvas->isFreshFrame());

    // Verify that full frame rects with different forms of opaque paint
    // trigger frames to be marked as fresh
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(255);
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, canvas->isFreshFrame());
    }
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(255);
        paint.setXfermodeMode(SkXfermode::kSrcIn_Mode);
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        SkBitmap bmp;
        create(&bmp, 0xFFFFFFFF);
        bmp.setAlphaType(kOpaque_SkAlphaType);
        SkShader* shader = SkShader::CreateBitmapShader(bmp,
            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
        paint.setShader(shader)->unref();
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, canvas->isFreshFrame());
    }

    // Verify that full frame rects with different forms of non-opaque paint
    // do not trigger frames to be marked as fresh
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(254);
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        // Defining a cone that partially overlaps the canvas
        const SkPoint pt1 = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
        const SkScalar r1 = SkIntToScalar(1);
        const SkPoint pt2 = SkPoint::Make(SkIntToScalar(10), SkIntToScalar(0));
        const SkScalar r2 = SkIntToScalar(5);
        const SkColor colors[2] = {SK_ColorWHITE, SK_ColorWHITE};
        const SkScalar pos[2] = {0, SK_Scalar1};
        SkShader* shader = SkGradientShader::CreateTwoPointConical(
            pt1, r1, pt2, r2, colors, pos, 2, SkShader::kClamp_TileMode);
        paint.setShader(shader)->unref();
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        SkBitmap bmp;
        create(&bmp, 0xFFFFFFFF);
        bmp.setAlphaType(kPremul_SkAlphaType);
        SkShader* shader = SkShader::CreateBitmapShader(bmp,
            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
        paint.setShader(shader)->unref();
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }

    // Verify that incomplete coverage does not trigger a fresh frame
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(255);
        canvas->drawRect(partialRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }

    // Verify that incomplete coverage due to clipping does not trigger a fresh
    // frame
    {
        canvas->save();
        canvas->clipRect(partialRect, SkRegion::kIntersect_Op, false);
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(255);
        canvas->drawRect(fullRect, paint);
        canvas->restore();
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }
    {
        canvas->save();
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(255);
        SkPath path;
        path.addCircle(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(2));
        canvas->clipPath(path, SkRegion::kIntersect_Op, false);
        canvas->drawRect(fullRect, paint);
        canvas->restore();
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }

    // Verify that stroked rect does not trigger a fresh frame
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setAlpha(255);
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, !canvas->isFreshFrame());
    }

    // Verify kSrcMode triggers a fresh frame even with transparent color
    {
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAlpha(100);
        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
        canvas->drawRect(fullRect, paint);
        REPORTER_ASSERT(reporter, canvas->isFreshFrame());
    }
}

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() {
        fPrepareForDrawCount = fStorageAllocatedChangedCount =
            fFlushedDrawCommandsCount = fSkippedPendingDrawCommandsCount = 0;
    }

    virtual void prepareForDraw() SK_OVERRIDE {
        fPrepareForDrawCount++;
    }
    virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {
        fStorageAllocatedChangedCount++;
    }
    virtual void flushedDrawCommands() SK_OVERRIDE {
        fFlushedDrawCommandsCount++;
    }
    virtual void skippedPendingDrawCommands() SK_OVERRIDE {
        fSkippedPendingDrawCommandsCount++;
    }

    int fPrepareForDrawCount;
    int fStorageAllocatedChangedCount;
    int fFlushedDrawCommandsCount;
    int fSkippedPendingDrawCommandsCount;

private:
    typedef SkDeferredCanvas::NotificationClient INHERITED;
};

// Verifies that the deferred canvas triggers a flush when its memory
// limit is exceeded
static void TestDeferredCanvasMemoryLimit(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    NotificationCounter notificationCounter;
    canvas->setNotificationClient(&notificationCounter);

    canvas->setMaxRecordingStorage(160000);

    SkBitmap sourceImage;
    // 100 by 100 image, takes 40,000 bytes in memory
    sourceImage.allocN32Pixels(100, 100);
    sourceImage.eraseColor(SK_ColorGREEN);

    for (int i = 0; i < 5; i++) {
        sourceImage.notifyPixelsChanged(); // to force re-serialization
        canvas->drawBitmap(sourceImage, 0, 0, NULL);
    }

    REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
}

static void TestDeferredCanvasSilentFlush(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(createSurface(0));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    NotificationCounter notificationCounter;
    canvas->setNotificationClient(&notificationCounter);

    canvas->silentFlush(); // will skip the initial clear that was recorded in createSurface

    REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawCommandsCount);
}

static void TestDeferredCanvasBitmapCaching(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    NotificationCounter notificationCounter;
    canvas->setNotificationClient(&notificationCounter);

    const int imageCount = 2;
    SkBitmap sourceImages[imageCount];
    for (int i = 0; i < imageCount; i++) {
        sourceImages[i].allocN32Pixels(100, 100);
        sourceImages[i].eraseColor(SK_ColorGREEN);
    }

    size_t bitmapSize = sourceImages[0].getSize();

    canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fStorageAllocatedChangedCount);
    // stored bitmap + drawBitmap command
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > bitmapSize);

    // verify that nothing can be freed at this point
    REPORTER_ASSERT(reporter, 0 == canvas->freeMemoryIfPossible(~0U));

    // verify that flush leaves image in cache
    REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter, 0 == notificationCounter.fPrepareForDrawCount);
    canvas->flush();
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fPrepareForDrawCount);
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() >= bitmapSize);

    // verify that after a flush, cached image can be freed
    REPORTER_ASSERT(reporter, canvas->freeMemoryIfPossible(~0U) >= bitmapSize);

    // Verify that caching works for avoiding multiple copies of the same bitmap
    canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
    REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
    canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
    REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < 2 * bitmapSize);

    // Verify partial eviction based on bytesToFree
    canvas->drawBitmap(sourceImages[1], 0, 0, NULL);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
    canvas->flush();
    REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2 * bitmapSize);
    size_t bytesFreed = canvas->freeMemoryIfPossible(1);
    REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount);
    REPORTER_ASSERT(reporter,  bytesFreed >= bitmapSize);
    REPORTER_ASSERT(reporter,  bytesFreed < 2*bitmapSize);

    // Verifiy that partial purge works, image zero is in cache but not reffed by
    // a pending draw, while image 1 is locked-in.
    canvas->freeMemoryIfPossible(~0U);
    REPORTER_ASSERT(reporter, 2 == notificationCounter.fFlushedDrawCommandsCount);
    canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
    canvas->flush();
    canvas->drawBitmap(sourceImages[1], 0, 0, NULL);
    bytesFreed = canvas->freeMemoryIfPossible(~0U);
    // only one bitmap should have been freed.
    REPORTER_ASSERT(reporter,  bytesFreed >= bitmapSize);
    REPORTER_ASSERT(reporter,  bytesFreed < 2*bitmapSize);
    // Clear for next test
    canvas->flush();
    canvas->freeMemoryIfPossible(~0U);
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < bitmapSize);

    // Verify the image cache is sensitive to genID bumps
    canvas->drawBitmap(sourceImages[1], 0, 0, NULL);
    sourceImages[1].notifyPixelsChanged();
    canvas->drawBitmap(sourceImages[1], 0, 0, NULL);
    REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() > 2*bitmapSize);

    // Verify that nothing in this test caused commands to be skipped
    REPORTER_ASSERT(reporter, 0 == notificationCounter.fSkippedPendingDrawCommandsCount);
}

static void TestDeferredCanvasSkip(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    NotificationCounter notificationCounter;
    canvas->setNotificationClient(&notificationCounter);
    canvas->clear(0x0);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawCommandsCount);
    REPORTER_ASSERT(reporter, 0 == notificationCounter.fFlushedDrawCommandsCount);
    canvas->flush();
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fSkippedPendingDrawCommandsCount);
    REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);

}

static void TestDeferredCanvasBitmapShaderNoLeak(skiatest::Reporter* reporter) {
    // This is a regression test for crbug.com/155875
    // This test covers a code path that inserts bitmaps into the bitmap heap through the
    // flattening of SkBitmapProcShaders. The refcount in the bitmap heap is maintained through
    // the flattening and unflattening of the shader.
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
    // test will fail if nbIterations is not in sync with
    // BITMAPS_TO_KEEP in SkGPipeWrite.cpp
    const int nbIterations = 5;
    size_t bytesAllocated = 0;
    for(int pass = 0; pass < 2; ++pass) {
        for(int i = 0; i < nbIterations; ++i) {
            SkPaint paint;
            SkBitmap paintPattern;
            paintPattern.allocN32Pixels(10, 10);
            paintPattern.eraseColor(SK_ColorGREEN);
            paint.setShader(SkNEW_ARGS(SkBitmapProcShader,
                (paintPattern, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)))->unref();
            canvas->drawPaint(paint);
            canvas->flush();

            // In the first pass, memory allocation should be monotonically increasing as
            // the bitmap heap slots fill up.  In the second pass memory allocation should be
            // stable as bitmap heap slots get recycled.
            size_t newBytesAllocated = canvas->storageAllocatedForRecording();
            if (pass == 0) {
                REPORTER_ASSERT(reporter, newBytesAllocated > bytesAllocated);
                bytesAllocated = newBytesAllocated;
            } else {
                REPORTER_ASSERT(reporter, newBytesAllocated == bytesAllocated);
            }
        }
    }
    // All cached resources should be evictable since last canvas call was flush()
    canvas->freeMemoryIfPossible(~0U);
    REPORTER_ASSERT(reporter, 0 == canvas->storageAllocatedForRecording());
}

static void TestDeferredCanvasBitmapSizeThreshold(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));

    SkBitmap sourceImage;
    // 100 by 100 image, takes 40,000 bytes in memory
    sourceImage.allocN32Pixels(100, 100);
    sourceImage.eraseColor(SK_ColorGREEN);

    // 1 under : should not store the image
    {
        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
        canvas->setBitmapSizeThreshold(39999);
        canvas->drawBitmap(sourceImage, 0, 0, NULL);
        size_t newBytesAllocated = canvas->storageAllocatedForRecording();
        REPORTER_ASSERT(reporter, newBytesAllocated == 0);
    }

    // exact value : should store the image
    {
        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
        canvas->setBitmapSizeThreshold(40000);
        canvas->drawBitmap(sourceImage, 0, 0, NULL);
        size_t newBytesAllocated = canvas->storageAllocatedForRecording();
        REPORTER_ASSERT(reporter, newBytesAllocated > 0);
    }

    // 1 over : should still store the image
    {
        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
        canvas->setBitmapSizeThreshold(40001);
        canvas->drawBitmap(sourceImage, 0, 0, NULL);
        size_t newBytesAllocated = canvas->storageAllocatedForRecording();
        REPORTER_ASSERT(reporter, newBytesAllocated > 0);
    }
}


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);
    int cnt;
#if SK_SUPPORT_GPU
    if (useGpu) {
        cnt = GrContextFactory::kGLContextTypeCnt;
    } else {
        cnt = 1;
    }
#else
    SkASSERT(!useGpu);
    cnt = 1;
#endif
    for (int i = 0; i < cnt; ++i) {
        SkSurface* surface;
#if SK_SUPPORT_GPU
        if (useGpu) {
            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
                continue;
            }
            GrContext* context = factory->get(glCtxType);
            if (NULL == context) {
                return;
            }

            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
        } else
#endif
        {
           surface = SkSurface::NewRaster(imageSpec);
        }
        SkASSERT(surface);
        SkAutoTUnref<SkSurface> aur(surface);
        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));

        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
        // it won't because rendering is deferred.
        canvas->clear(SK_ColorBLACK);
        // 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.
        SkImage* image2 = surface->newImageSnapshot();
        SkAutoTUnref<SkImage> aur_i2(image2);
        // Images identical because of deferral
        REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID());
        // 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
        // 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);
    }
}

static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
    SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10);
    SkSurface* surface;
    SkSurface* alternateSurface;
    bool useGpu = SkToBool(factory);
    int cnt;
#if SK_SUPPORT_GPU
    if (useGpu) {
        cnt = GrContextFactory::kGLContextTypeCnt;
    } else {
        cnt = 1;
    }
#else
    SkASSERT(!useGpu);
    cnt = 1;
#endif

    for (int i = 0; i < cnt; ++i) {
#if SK_SUPPORT_GPU
        if (useGpu) {
            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
                continue;
            }
            GrContext* context = factory->get(glCtxType);
            if (NULL == context) {
                continue;
            }
            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
            alternateSurface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
        } else
#endif
        {
            surface = SkSurface::NewRaster(imageSpec);
            alternateSurface = SkSurface::NewRaster(imageSpec);
        }
        SkASSERT(surface);
        SkASSERT(alternateSurface);
        SkAutoTUnref<SkSurface> aur1(surface);
        SkAutoTUnref<SkSurface> aur2(alternateSurface);
        PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
        PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu);
        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.
        canvas->clear(SK_ColorWHITE);
        canvas->flush();
        REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
        REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != pixels2);
    }
}

static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporter) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));

    NotificationCounter notificationCounter;
    canvas->setNotificationClient(&notificationCounter);

    SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
    SkAutoTUnref<SkSurface> secondarySurface(canvas->newSurface(info));

    SkRect rect = SkRect::MakeWH(5, 5);
    SkPaint paint;
    // After spawning a compatible canvas:
    // 1) Verify that secondary canvas is usable and does not report to the notification client.
    surface->getCanvas()->drawRect(rect, paint);
    REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount == 0);
    // 2) Verify that original canvas is usable and still reports to the notification client.
    canvas->drawRect(rect, paint);
    REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount == 1);
}

static void TestDeferredCanvasGetCanvasSize(skiatest::Reporter* reporter) {
    SkRect rect;
    rect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth), SkIntToScalar(gHeight));
    SkRect clip;
    clip.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(1), SkIntToScalar(1));

    SkPaint paint;
    SkISize size = SkISize::Make(gWidth, gHeight);

    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
    SkSurface* newSurface = SkSurface::NewRasterPMColor(4, 4);
    SkAutoTUnref<SkSurface> aur(newSurface);

    for (int i = 0; i < 2; ++i) {
        if (i == 1) {
            canvas->setSurface(newSurface);
            size = SkISize::Make(4, 4);
        }

        // verify that canvas size is correctly initialized or set
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that clear, clip and draw the canvas will not change its size
        canvas->clear(0x00000000);
        canvas->clipRect(clip, SkRegion::kIntersect_Op, false);
        canvas->drawRect(rect, paint);
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that flush the canvas will not change its size
        canvas->flush();
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that clear canvas with saved state will not change its size
        canvas->save();
        canvas->clear(0xFFFFFFFF);
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that restore canvas state will not change its size
        canvas->restore();
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that clear within a layer will not change canvas size
        canvas->saveLayer(&clip, &paint);
        canvas->clear(0x00000000);
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());

        // Verify that restore from a layer will not change canvas size
        canvas->restore();
        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
    }
}

DEF_TEST(DeferredCanvas_CPU, reporter) {
    TestDeferredCanvasFlush(reporter);
    TestDeferredCanvasSilentFlush(reporter);
    TestDeferredCanvasFreshFrame(reporter);
    TestDeferredCanvasMemoryLimit(reporter);
    TestDeferredCanvasBitmapCaching(reporter);
    TestDeferredCanvasSkip(reporter);
    TestDeferredCanvasBitmapShaderNoLeak(reporter);
    TestDeferredCanvasBitmapSizeThreshold(reporter);
    TestDeferredCanvasCreateCompatibleDevice(reporter);
    TestDeferredCanvasWritePixelsToSurface(reporter);
    TestDeferredCanvasGetCanvasSize(reporter);
    TestDeferredCanvasSurface(reporter, NULL);
    TestDeferredCanvasSetSurface(reporter, NULL);
}

DEF_GPUTEST(DeferredCanvas_GPU, reporter, factory) {
    if (factory != NULL) {
        TestDeferredCanvasSurface(reporter, factory);
        TestDeferredCanvasSetSurface(reporter, factory);
    }
}
