/*
 * 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::NewRasterN32Premul(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);
    }

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

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

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

    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 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;
    }

    void prepareForDraw() SK_OVERRIDE {
        fPrepareForDrawCount++;
    }
    void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {
        fStorageAllocatedChangedCount++;
    }
    void flushedDrawCommands() SK_OVERRIDE {
        fFlushedDrawCommandsCount++;
    }
    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::NewRasterN32Premul(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::NewRasterN32Premul(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::NewRasterN32Premul(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::NewRasterN32Premul(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::NewRasterN32Premul(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::NewRasterN32Premul(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::NewRasterN32Premul(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);
    }
}
