1995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org/*
2995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * Copyright 2013 Google Inc.
3995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org *
4995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * Use of this source code is governed by a BSD-style license that can be
5995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org * found in the LICENSE file.
6995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org */
74ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org
8995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkCanvas.h"
94f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkData.h"
104f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkImageEncoder.h"
11995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkRRect.h"
12995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "SkSurface.h"
134f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com#include "SkUtils.h"
14995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "Test.h"
15995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
16995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#if SK_SUPPORT_GPU
17995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#include "GrContextFactory.h"
18995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#else
19995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.orgclass GrContextFactory;
20995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.orgclass GrContext;
21995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#endif
22995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
23995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.orgenum SurfaceType {
24995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    kRaster_SurfaceType,
25c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    kRasterDirect_SurfaceType,
26995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    kGpu_SurfaceType,
27d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    kGpuScratch_SurfaceType,
28995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org};
29995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
30982542dce8acbd2f3e7642268b21e76b93230dafreedstatic void release_storage(void* pixels, void* context) {
31982542dce8acbd2f3e7642268b21e76b93230dafreed    SkASSERT(pixels == context);
32982542dce8acbd2f3e7642268b21e76b93230dafreed    sk_free(pixels);
33982542dce8acbd2f3e7642268b21e76b93230dafreed}
34c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
35c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgstatic SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
36c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org                                SkImageInfo* requestedInfo = NULL) {
37982542dce8acbd2f3e7642268b21e76b93230dafreed    static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
38c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
39c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    if (requestedInfo) {
40c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        *requestedInfo = info;
41c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    }
42995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
43995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    switch (surfaceType) {
44c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        case kRaster_SurfaceType:
45c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org            return SkSurface::NewRaster(info);
46982542dce8acbd2f3e7642268b21e76b93230dafreed        case kRasterDirect_SurfaceType: {
47982542dce8acbd2f3e7642268b21e76b93230dafreed            const size_t rowBytes = info.minRowBytes();
48982542dce8acbd2f3e7642268b21e76b93230dafreed            void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
49982542dce8acbd2f3e7642268b21e76b93230dafreed            return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
50982542dce8acbd2f3e7642268b21e76b93230dafreed                                                         release_storage, storage);
51982542dce8acbd2f3e7642268b21e76b93230dafreed        }
52c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        case kGpu_SurfaceType:
53afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon            return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0, NULL);
54d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org        case kGpuScratch_SurfaceType:
55afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon            return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted, info, 0, NULL);
56995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    }
57995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    return NULL;
58995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org}
59995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
604f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.comenum ImageType {
614f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    kRasterCopy_ImageType,
624f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    kRasterData_ImageType,
634f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    kGpu_ImageType,
644f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    kCodec_ImageType,
654f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com};
66999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com
67b2497c2d945c0a5d770865b026e2d5947bf37c91reed#include "SkImageGenerator.h"
68b2497c2d945c0a5d770865b026e2d5947bf37c91reed
69b2497c2d945c0a5d770865b026e2d5947bf37c91reedclass EmptyGenerator : public SkImageGenerator {
703ef71e343bf075888fb50892350390b4dd47de24reedpublic:
713ef71e343bf075888fb50892350390b4dd47de24reed    EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
72b2497c2d945c0a5d770865b026e2d5947bf37c91reed};
73b2497c2d945c0a5d770865b026e2d5947bf37c91reed
74b2497c2d945c0a5d770865b026e2d5947bf37c91reedstatic void test_empty_image(skiatest::Reporter* reporter) {
75b2497c2d945c0a5d770865b026e2d5947bf37c91reed    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
76b2497c2d945c0a5d770865b026e2d5947bf37c91reed
77b2497c2d945c0a5d770865b026e2d5947bf37c91reed    REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterCopy(info, NULL, 0));
78b2497c2d945c0a5d770865b026e2d5947bf37c91reed    REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterData(info, NULL, 0));
79b2497c2d945c0a5d770865b026e2d5947bf37c91reed    REPORTER_ASSERT(reporter, NULL == SkImage::NewFromGenerator(SkNEW(EmptyGenerator)));
80b2497c2d945c0a5d770865b026e2d5947bf37c91reed}
81b2497c2d945c0a5d770865b026e2d5947bf37c91reed
82b2497c2d945c0a5d770865b026e2d5947bf37c91reedstatic void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) {
83b2497c2d945c0a5d770865b026e2d5947bf37c91reed    const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
84b2497c2d945c0a5d770865b026e2d5947bf37c91reed
85b2497c2d945c0a5d770865b026e2d5947bf37c91reed    REPORTER_ASSERT(reporter, NULL == SkSurface::NewRaster(info));
86b2497c2d945c0a5d770865b026e2d5947bf37c91reed    REPORTER_ASSERT(reporter, NULL == SkSurface::NewRasterDirect(info, NULL, 0));
87b2497c2d945c0a5d770865b026e2d5947bf37c91reed    if (ctx) {
88afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        REPORTER_ASSERT(reporter, NULL ==
89afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon                        SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0, NULL));
90b2497c2d945c0a5d770865b026e2d5947bf37c91reed    }
91b2497c2d945c0a5d770865b026e2d5947bf37c91reed}
92b2497c2d945c0a5d770865b026e2d5947bf37c91reed
93e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon#if SK_SUPPORT_GPU
94e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomonstatic void test_wrapped_texture_surface(skiatest::Reporter* reporter, GrContext* ctx) {
95e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    if (NULL == ctx) {
96e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon        return;
97e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    }
98e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    // Test the wrapped factory for SkSurface by creating a texture using ctx and then treat it as
99e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    // an external texture and wrap it in a SkSurface.
100e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
101e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    GrSurfaceDesc texDesc;
102e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    texDesc.fConfig = kRGBA_8888_GrPixelConfig;
103e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    texDesc.fFlags = kRenderTarget_GrSurfaceFlag;
104e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    texDesc.fWidth = texDesc.fHeight = 100;
105e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    texDesc.fSampleCnt = 0;
106e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
107d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrSurface> dummySurface(ctx->textureProvider()->createTexture(texDesc, false));
108e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
109e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    REPORTER_ASSERT(reporter, dummySurface && dummySurface->asTexture() &&
110e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon                              dummySurface->asRenderTarget());
111e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    if (!dummySurface || !dummySurface->asTexture() || !dummySurface->asRenderTarget()) {
112e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon        return;
113e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    }
114e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
115e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    GrBackendObject textureHandle = dummySurface->asTexture()->getTextureHandle();
116e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
117e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    GrBackendTextureDesc wrappedDesc;
118e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fConfig = dummySurface->config();
119e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fWidth = dummySurface->width();
120e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fHeight = dummySurface->height();
121e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fOrigin = dummySurface->origin();
122e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fSampleCnt = dummySurface->asRenderTarget()->numSamples();
123e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
124e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    wrappedDesc.fTextureHandle = textureHandle;
125e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
126e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    SkAutoTUnref<SkSurface> surface(SkSurface::NewWrappedRenderTarget(ctx, wrappedDesc, NULL));
127e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon    REPORTER_ASSERT(reporter, surface);
128e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon}
129e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon#endif
130e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
131e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon
132999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.comstatic void test_image(skiatest::Reporter* reporter) {
133999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
134999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    size_t rowBytes = info.minRowBytes();
135999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    size_t size = info.getSafeSize(rowBytes);
1369594da111dc1c36c1912eb61207aaa54c17ea550reed    SkData* data = SkData::NewUninitialized(size);
1375e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
138bbb61d7268b26d240afde2c924cb7d1370aa4071mtklein    REPORTER_ASSERT(reporter, data->unique());
139999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
140bbb61d7268b26d240afde2c924cb7d1370aa4071mtklein    REPORTER_ASSERT(reporter, !data->unique());
141999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    image->unref();
142bbb61d7268b26d240afde2c924cb7d1370aa4071mtklein    REPORTER_ASSERT(reporter, data->unique());
143999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    data->unref();
144999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com}
145999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com
14667f2eb45b9fb6f20e31d8c1f22ae1b8291618525reedstatic SkImage* createImage(ImageType imageType, GrContext* context, SkColor color) {
1474f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    const SkPMColor pmcolor = SkPreMultiplyColor(color);
1484f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
1494f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    const size_t rowBytes = info.minRowBytes();
150e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const size_t size = rowBytes * info.height();
1514f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com
1529594da111dc1c36c1912eb61207aaa54c17ea550reed    SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
1539594da111dc1c36c1912eb61207aaa54c17ea550reed    void* addr = data->writable_data();
1544f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2));
1554f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com
1564f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    switch (imageType) {
1574f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        case kRasterCopy_ImageType:
1584f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            return SkImage::NewRasterCopy(info, addr, rowBytes);
1594f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        case kRasterData_ImageType:
1604f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            return SkImage::NewRasterData(info, data, rowBytes);
16167f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        case kGpu_ImageType: {
162afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon            SkAutoTUnref<SkSurface> surf(
163afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
16467f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed            surf->getCanvas()->clear(color);
16567f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed            return surf->newImageSnapshot();
16667f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        }
1674f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        case kCodec_ImageType: {
1684f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            SkBitmap bitmap;
16900f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org            bitmap.installPixels(info, addr, rowBytes);
1704f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            SkAutoTUnref<SkData> src(
17167f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed                 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
1725965c8ae4ee960275da4bc40189bdba85aab8b5ereed            return SkImage::NewFromData(src);
1734f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        }
1744f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    }
1754f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    SkASSERT(false);
1764f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    return NULL;
1774f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com}
1784f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com
17996472deea70169396b8e1f576e470138f55fdb1freedstatic void set_pixels(SkPMColor pixels[], int count, SkPMColor color) {
18096472deea70169396b8e1f576e470138f55fdb1freed    sk_memset32(pixels, color, count);
18196472deea70169396b8e1f576e470138f55fdb1freed}
18296472deea70169396b8e1f576e470138f55fdb1freedstatic bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
18396472deea70169396b8e1f576e470138f55fdb1freed    for (int i = 0; i < count; ++i) {
18496472deea70169396b8e1f576e470138f55fdb1freed        if (pixels[i] != expected) {
18596472deea70169396b8e1f576e470138f55fdb1freed            return false;
18696472deea70169396b8e1f576e470138f55fdb1freed        }
18796472deea70169396b8e1f576e470138f55fdb1freed    }
18896472deea70169396b8e1f576e470138f55fdb1freed    return true;
18996472deea70169396b8e1f576e470138f55fdb1freed}
19096472deea70169396b8e1f576e470138f55fdb1freed
19196472deea70169396b8e1f576e470138f55fdb1freedstatic void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image,
19296472deea70169396b8e1f576e470138f55fdb1freed                                  SkPMColor expected) {
19396472deea70169396b8e1f576e470138f55fdb1freed    const SkPMColor notExpected = ~expected;
19496472deea70169396b8e1f576e470138f55fdb1freed
19596472deea70169396b8e1f576e470138f55fdb1freed    const int w = 2, h = 2;
19696472deea70169396b8e1f576e470138f55fdb1freed    const size_t rowBytes = w * sizeof(SkPMColor);
19796472deea70169396b8e1f576e470138f55fdb1freed    SkPMColor pixels[w*h];
19896472deea70169396b8e1f576e470138f55fdb1freed
19996472deea70169396b8e1f576e470138f55fdb1freed    SkImageInfo info;
20096472deea70169396b8e1f576e470138f55fdb1freed
20196472deea70169396b8e1f576e470138f55fdb1freed    info = SkImageInfo::MakeUnknown(w, h);
20296472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
20396472deea70169396b8e1f576e470138f55fdb1freed
20496472deea70169396b8e1f576e470138f55fdb1freed    // out-of-bounds should fail
20596472deea70169396b8e1f576e470138f55fdb1freed    info = SkImageInfo::MakeN32Premul(w, h);
20696472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
20796472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
20896472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
20996472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
21096472deea70169396b8e1f576e470138f55fdb1freed
21196472deea70169396b8e1f576e470138f55fdb1freed    // top-left should succeed
21296472deea70169396b8e1f576e470138f55fdb1freed    set_pixels(pixels, w*h, notExpected);
21396472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
21496472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
21596472deea70169396b8e1f576e470138f55fdb1freed
21696472deea70169396b8e1f576e470138f55fdb1freed    // bottom-right should succeed
21796472deea70169396b8e1f576e470138f55fdb1freed    set_pixels(pixels, w*h, notExpected);
21896472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
21996472deea70169396b8e1f576e470138f55fdb1freed                                                image->width() - w, image->height() - h));
22096472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
22196472deea70169396b8e1f576e470138f55fdb1freed
22296472deea70169396b8e1f576e470138f55fdb1freed    // partial top-left should succeed
22396472deea70169396b8e1f576e470138f55fdb1freed    set_pixels(pixels, w*h, notExpected);
22496472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
22596472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, pixels[3] == expected);
22696472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
22796472deea70169396b8e1f576e470138f55fdb1freed
22896472deea70169396b8e1f576e470138f55fdb1freed    // partial bottom-right should succeed
22996472deea70169396b8e1f576e470138f55fdb1freed    set_pixels(pixels, w*h, notExpected);
23096472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
23196472deea70169396b8e1f576e470138f55fdb1freed                                                image->width() - 1, image->height() - 1));
23296472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, pixels[0] == expected);
23396472deea70169396b8e1f576e470138f55fdb1freed    REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
23496472deea70169396b8e1f576e470138f55fdb1freed}
23596472deea70169396b8e1f576e470138f55fdb1freed
23667f2eb45b9fb6f20e31d8c1f22ae1b8291618525reedstatic void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
2374f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    static const struct {
2384f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        ImageType   fType;
2394f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        bool        fPeekShouldSucceed;
24067f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        const char* fName;
2414f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    } gRec[] = {
24267f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        { kRasterCopy_ImageType,    true,       "RasterCopy"    },
24367f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        { kRasterData_ImageType,    true,       "RasterData"    },
24467f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        { kGpu_ImageType,           false,      "Gpu"           },
24567f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        { kCodec_ImageType,         false,      "Codec"         },
2464f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    };
24702d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com
2484f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    const SkColor color = SK_ColorRED;
2494f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    const SkPMColor pmcolor = SkPreMultiplyColor(color);
25002d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com
25167f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed    GrContext* ctx = NULL;
25267f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed#if SK_SUPPORT_GPU
25367f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed    ctx = factory->get(GrContextFactory::kNative_GLContextType);
254c8e934007a48465e584cdeed9ef02077d3cd5451senorblanco    if (NULL == ctx) {
25584bfd3958f0da2049425a8f33e49f81cd58ba0e2senorblanco        return;
25684bfd3958f0da2049425a8f33e49f81cd58ba0e2senorblanco    }
25767f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed#endif
25867f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed
2594f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
2604f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        SkImageInfo info;
2614f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        size_t rowBytes;
26202d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com
26367f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed        SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color));
2644f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        if (!image.get()) {
26567f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed            SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
2664f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            continue;   // gpu may not be enabled
2674f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        }
2684f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        const void* addr = image->peekPixels(&info, &rowBytes);
26949f085dddff10473b6ebf832a974288300224e60bsalomon        bool success = SkToBool(addr);
2704f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
2714f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        if (success) {
272e5ea500d4714a7d84de2bf913e81be3b65d2de68reed            REPORTER_ASSERT(reporter, 10 == info.width());
273e5ea500d4714a7d84de2bf913e81be3b65d2de68reed            REPORTER_ASSERT(reporter, 10 == info.height());
274e5ea500d4714a7d84de2bf913e81be3b65d2de68reed            REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
275e5ea500d4714a7d84de2bf913e81be3b65d2de68reed            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
276e5ea500d4714a7d84de2bf913e81be3b65d2de68reed                            kOpaque_SkAlphaType == info.alphaType());
2774f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
2784f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com            REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
2794f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com        }
28096472deea70169396b8e1f576e470138f55fdb1freed
28196472deea70169396b8e1f576e470138f55fdb1freed        test_image_readpixels(reporter, image, pmcolor);
2824f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com    }
2834f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com}
2844f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com
285c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgstatic void test_canvaspeek(skiatest::Reporter* reporter,
286c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org                            GrContextFactory* factory) {
287c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    static const struct {
288c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        SurfaceType fType;
289c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        bool        fPeekShouldSucceed;
290c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    } gRec[] = {
291c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        { kRaster_SurfaceType,          true    },
292c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        { kRasterDirect_SurfaceType,    true    },
293c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org#if SK_SUPPORT_GPU
294c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        { kGpu_SurfaceType,             false   },
295d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org        { kGpuScratch_SurfaceType,      false   },
296c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org#endif
297c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    };
298c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
299c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    const SkColor color = SK_ColorRED;
300c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    const SkPMColor pmcolor = SkPreMultiplyColor(color);
301c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
302e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon    int cnt;
303c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org#if SK_SUPPORT_GPU
304e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon    cnt = GrContextFactory::kGLContextTypeCnt;
305e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon#else
306e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon    cnt = 1;
307c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org#endif
308c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
309e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon    for (int i= 0; i < cnt; ++i) {
310e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        GrContext* context = NULL;
311e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon#if SK_SUPPORT_GPU
312e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
313e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
314e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            continue;
315e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        }
316e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        context = factory->get(glCtxType);
317c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
318e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        if (NULL == context) {
319e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            continue;
320e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        }
321e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon#endif
322e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
323e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            SkImageInfo info, requestInfo;
324e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            size_t rowBytes;
325e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon
326e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
327e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                                                          &requestInfo));
328e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            surface->getCanvas()->clear(color);
329e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon
330e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
33149f085dddff10473b6ebf832a974288300224e60bsalomon            bool success = SkToBool(addr);
332e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
333e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon
334e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            SkImageInfo info2;
335e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            size_t rb2;
336e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            const void* addr2 = surface->peekPixels(&info2, &rb2);
337e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon
338e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            if (success) {
339e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, requestInfo == info);
340e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
341e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
342e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon
343e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, addr2 == addr);
344e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, info2 == info);
345e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, rb2 == rowBytes);
346e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            } else {
347e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                REPORTER_ASSERT(reporter, NULL == addr2);
348e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            }
349c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        }
350c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    }
351c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org}
352c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
353995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.orgstatic void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
354995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org                                   GrContext* context) {
355995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    // Verify that the right canvas commands trigger a copy on write
356995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkSurface* surface = createSurface(surfaceType, context);
357995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkAutoTUnref<SkSurface> aur_surface(surface);
358995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkCanvas* canvas = surface->getCanvas();
359995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
360995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkRect testRect =
361995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
362995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org                         SkIntToScalar(4), SkIntToScalar(5));
363995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkPath testPath;
364995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    testPath.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
365995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org                                      SkIntToScalar(2), SkIntToScalar(1)));
366995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
367995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkIRect testIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
368995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
369995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkRegion testRegion;
370995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    testRegion.setRect(testIRect);
371995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
372995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
373995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkColor testColor = 0x01020304;
374995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkPaint testPaint;
375995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkPoint testPoints[3] = {
376995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        {SkIntToScalar(0), SkIntToScalar(0)},
377995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        {SkIntToScalar(2), SkIntToScalar(1)},
378995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        {SkIntToScalar(0), SkIntToScalar(2)}
379995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    };
380995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const size_t testPointCount = 3;
381995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
382995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkBitmap testBitmap;
383deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org    testBitmap.allocN32Pixels(10, 10);
384d1ce77d548ab098c2f455e9b0fa1f195e75cd8edrobertphillips@google.com    testBitmap.eraseColor(0);
385995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
386995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkRRect testRRect;
387995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    testRRect.setRectXY(testRect, SK_Scalar1, SK_Scalar1);
388995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
389995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    SkString testText("Hello World");
390995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    const SkPoint testPoints2[] = {
391995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(0), SkIntToScalar(1) },
392995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(1), SkIntToScalar(1) },
393995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(2), SkIntToScalar(1) },
394995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(3), SkIntToScalar(1) },
395995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(4), SkIntToScalar(1) },
396995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(5), SkIntToScalar(1) },
397995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(6), SkIntToScalar(1) },
398995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(7), SkIntToScalar(1) },
399995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(8), SkIntToScalar(1) },
400995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(9), SkIntToScalar(1) },
401995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        { SkIntToScalar(10), SkIntToScalar(1) },
402995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    };
403995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
404995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#define EXPECT_COPY_ON_WRITE(command)                               \
405995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    {                                                               \
4065ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org        SkImage* imageBefore = surface->newImageSnapshot();         \
407995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        SkAutoTUnref<SkImage> aur_before(imageBefore);              \
408995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        canvas-> command ;                                          \
4095ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org        SkImage* imageAfter = surface->newImageSnapshot();          \
410995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        SkAutoTUnref<SkImage> aur_after(imageAfter);                \
411995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        REPORTER_ASSERT(reporter, imageBefore != imageAfter);       \
412995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    }
413995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
414995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(clear(testColor))
415995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawPaint(testPaint))
416995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawPoints(SkCanvas::kPoints_PointMode, testPointCount, testPoints, \
417995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        testPaint))
418995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawOval(testRect, testPaint))
419995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawRect(testRect, testPaint))
420995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawRRect(testRRect, testPaint))
421995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawPath(testPath, testPaint))
422995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawBitmap(testBitmap, 0, 0))
423995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawBitmapRect(testBitmap, NULL, testRect))
424995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawBitmapNine(testBitmap, testIRect, testRect, NULL))
425995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawSprite(testBitmap, 0, 0, NULL))
426995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawText(testText.c_str(), testText.size(), 0, 1, testPaint))
427995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawPosText(testText.c_str(), testText.size(), testPoints2, \
428995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        testPaint))
429995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org    EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, NULL, \
430995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org        testPaint))
431995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org}
432995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
433af0583528c7dd5344abfe14347377011abe374e2junov@chromium.orgstatic void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter,
434af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org                                                    SurfaceType surfaceType,
435af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org                                                    GrContext* context) {
436af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    // This test succeeds by not triggering an assertion.
437af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    // The test verifies that the surface remains writable (usable) after
438af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    // acquiring and releasing a snapshot without triggering a copy on write.
4394d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
440af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    SkCanvas* canvas = surface->getCanvas();
441af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    canvas->clear(1);
4425ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org    surface->newImageSnapshot()->unref();  // Create and destroy SkImage
4434d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas->clear(2);  // Must not assert internally
444995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org}
445da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org
446b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU
4474d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.orgstatic void Test_crbug263329(skiatest::Reporter* reporter,
448d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org                             SurfaceType surfaceType,
4494d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org                             GrContext* context) {
4504d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // This is a regression test for crbug.com/263329
4514d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // Bug was caused by onCopyOnWrite releasing the old surface texture
4524d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // back to the scratch texture pool even though the texture is used
4534d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // by and active SkImage_Gpu.
454d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    SkAutoTUnref<SkSurface> surface1(createSurface(surfaceType, context));
455d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    SkAutoTUnref<SkSurface> surface2(createSurface(surfaceType, context));
4564d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkCanvas* canvas1 = surface1->getCanvas();
4574d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkCanvas* canvas2 = surface2->getCanvas();
4584d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas1->clear(1);
4594d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkAutoTUnref<SkImage> image1(surface1->newImageSnapshot());
4604d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // Trigger copy on write, new backing is a scratch texture
4614d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas1->clear(2);
4624d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkAutoTUnref<SkImage> image2(surface1->newImageSnapshot());
4634d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // Trigger copy on write, old backing should not be returned to scratch
4644d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // pool because it is held by image2
4654d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas1->clear(3);
4664d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org
4674d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas2->clear(4);
4684d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkAutoTUnref<SkImage> image3(surface2->newImageSnapshot());
4694d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // Trigger copy on write on surface2. The new backing store should not
4704d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // be recycling a texture that is held by an existing image.
4714d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    canvas2->clear(5);
4724d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    SkAutoTUnref<SkImage> image4(surface2->newImageSnapshot());
4734d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image4->getTexture() != image3->getTexture());
4744d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    // The following assertion checks crbug.com/263329
4754d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image4->getTexture() != image2->getTexture());
4764d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image4->getTexture() != image1->getTexture());
4774d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image3->getTexture() != image2->getTexture());
4784d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image3->getTexture() != image1->getTexture());
4794d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org    REPORTER_ASSERT(reporter, image2->getTexture() != image1->getTexture());
4804d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org}
4814d24b747e272355395f456e088a2d0177c00ddb5commit-bot@chromium.org
482da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.orgstatic void TestGetTexture(skiatest::Reporter* reporter,
483da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org                                 SurfaceType surfaceType,
484da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org                                 GrContext* context) {
485da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
486da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
487da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    GrTexture* texture = image->getTexture();
488d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) {
48949f085dddff10473b6ebf832a974288300224e60bsalomon        REPORTER_ASSERT(reporter, texture);
490da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org        REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle());
491da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    } else {
492da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org        REPORTER_ASSERT(reporter, NULL == texture);
493da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    }
494da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
495da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    REPORTER_ASSERT(reporter, image->getTexture() == texture);
496da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org}
497eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
4983582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h"
499eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkGpuDevice.h"
500eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkImage_Gpu.h"
501eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon#include "SkSurface_Gpu.h"
502eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
503eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomonSkSurface::Budgeted is_budgeted(SkSurface* surf) {
5043582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    return ((SkSurface_Gpu*)surf)->getDevice()->accessRenderTarget()->resourcePriv().isBudgeted() ?
505eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon        SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
506eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon}
507eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
508eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomonSkSurface::Budgeted is_budgeted(SkImage* image) {
5093582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    return ((SkImage_Gpu*)image)->getTexture()->resourcePriv().isBudgeted() ?
510eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon        SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
511eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon}
512eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
513eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomonstatic void test_surface_budget(skiatest::Reporter* reporter, GrContext* context) {
514eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon    SkImageInfo info = SkImageInfo::MakeN32Premul(8,8);
515eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon    for (int i = 0; i < 2; ++i) {
516eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon        SkSurface::Budgeted sbudgeted = i ? SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
517eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon        for (int j = 0; j < 2; ++j) {
518eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            SkSurface::Budgeted ibudgeted = j ? SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
519eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            SkAutoTUnref<SkSurface>
520eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon                surface(SkSurface::NewRenderTarget(context, sbudgeted, info, 0));
521eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            SkASSERT(surface);
522eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface));
523eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
52431ff29829e3ceb8f5af0a655285d83abb6662c85mtklein            SkAutoTUnref<SkImage> image(surface->newImageSnapshot(ibudgeted));
525eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
526eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            // Initially the image shares a texture with the surface, and the surface decides
527eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            // whether it is budgeted or not.
528eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface));
529eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(image));
530eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
531eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            // Now trigger copy-on-write
532eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            surface->getCanvas()->clear(SK_ColorBLUE);
533eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
534eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            // They don't share a texture anymore. They should each have made their own budget
535eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            // decision.
536eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            REPORTER_ASSERT(reporter, sbudgeted == is_budgeted(surface));
537eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon            REPORTER_ASSERT(reporter, ibudgeted == is_budgeted(image));
538eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon        }
539eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon    }
540eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon}
541eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon
542b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#endif
543da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org
544acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.orgstatic void TestSurfaceNoCanvas(skiatest::Reporter* reporter,
545acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org                                          SurfaceType surfaceType,
546c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org                                          GrContext* context,
547c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org                                          SkSurface::ContentChangeMode mode) {
548acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    // Verifies the robustness of SkSurface for handling use cases where calls
549acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    // are made before a canvas is created.
550acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    {
551acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        // Test passes by not asserting
552acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkSurface* surface = createSurface(surfaceType, context);
553acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkAutoTUnref<SkSurface> aur_surface(surface);
554c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        surface->notifyContentWillChange(mode);
55503087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(surface->validate();)
556acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    }
557acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    {
558acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkSurface* surface = createSurface(surfaceType, context);
559acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkAutoTUnref<SkSurface> aur_surface(surface);
560acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkImage* image1 = surface->newImageSnapshot();
561acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkAutoTUnref<SkImage> aur_image1(image1);
56203087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(image1->validate();)
56303087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(surface->validate();)
564c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        surface->notifyContentWillChange(mode);
56503087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(image1->validate();)
56603087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(surface->validate();)
567acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkImage* image2 = surface->newImageSnapshot();
568acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        SkAutoTUnref<SkImage> aur_image2(image2);
56903087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(image2->validate();)
57003087072483378a43f7b3f7a47944614187275ebrobertphillips@google.com        SkDEBUGCODE(surface->validate();)
571acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org        REPORTER_ASSERT(reporter, image1 != image2);
572acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org    }
57345fb8b60137c65106b7903285672d0f8a8041f97skia.committer@gmail.com
574acea3ef448c9903de3aa6a013c839dce577e6ce3junov@chromium.org}
575995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org
5764ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(Surface, reporter, factory) {
577999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com    test_image(reporter);
578999da9c5e45fb533efe8782c9096794b9ad1c1b3reed@google.com
579af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, NULL);
580af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, NULL);
581c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kDiscard_ContentChangeMode);
582c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kRetain_ContentChangeMode);
583c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
584b2497c2d945c0a5d770865b026e2d5947bf37c91reed    test_empty_image(reporter);
585b2497c2d945c0a5d770865b026e2d5947bf37c91reed    test_empty_surface(reporter, NULL);
586b2497c2d945c0a5d770865b026e2d5947bf37c91reed
58767f2eb45b9fb6f20e31d8c1f22ae1b8291618525reed    test_imagepeek(reporter, factory);
588c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    test_canvaspeek(reporter, factory);
589c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
590b516a4177931b8febf859752b49f094f70539eaejunov@chromium.org#if SK_SUPPORT_GPU
591da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org    TestGetTexture(reporter, kRaster_SurfaceType, NULL);
59249f085dddff10473b6ebf832a974288300224e60bsalomon    if (factory) {
593e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon        for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
594e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
595e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
596e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                continue;
597e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            }
598e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            GrContext* context = factory->get(glCtxType);
59949f085dddff10473b6ebf832a974288300224e60bsalomon            if (context) {
600e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                Test_crbug263329(reporter, kGpu_SurfaceType, context);
601e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                Test_crbug263329(reporter, kGpuScratch_SurfaceType, context);
602e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
603e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context);
604e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
605e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_SurfaceType, context);
606e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
607e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
608e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
609e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
610e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestGetTexture(reporter, kGpu_SurfaceType, context);
611e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon                TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
612b2497c2d945c0a5d770865b026e2d5947bf37c91reed                test_empty_surface(reporter, context);
613eaaaf0b16c4e55ff8a48c5ac1ed623a6ba469053bsalomon                test_surface_budget(reporter, context);
614e4579adfdfb4b9f195d162835a69d9c2a974a6acbsalomon                test_wrapped_texture_surface(reporter, context);
615e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon            }
6163bddb38e6468c6294e40e5307f05e6b56bdd6a6crobertphillips@google.com        }
617af0583528c7dd5344abfe14347377011abe374e2junov@chromium.org    }
618995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org#endif
619995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org}
6208b26b99c97473f020df4b9d4ba789e074e06ceddreed
6218b26b99c97473f020df4b9d4ba789e074e06ceddreed#if SK_SUPPORT_GPU
6228b26b99c97473f020df4b9d4ba789e074e06ceddreedstatic SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject texID, bool doCopy) {
6238b26b99c97473f020df4b9d4ba789e074e06ceddreed    GrBackendTextureDesc desc;
6248b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fConfig = kSkia8888_GrPixelConfig;
6258b26b99c97473f020df4b9d4ba789e074e06ceddreed    // need to be a rendertarget for now...
6268b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
6278b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fWidth = w;
6288b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fHeight = h;
6298b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fSampleCnt = 0;
6308b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fTextureHandle = texID;
6318b26b99c97473f020df4b9d4ba789e074e06ceddreed    return doCopy ? SkImage::NewFromTextureCopy(ctx, desc) : SkImage::NewFromTexture(ctx, desc);
6328b26b99c97473f020df4b9d4ba789e074e06ceddreed}
6338b26b99c97473f020df4b9d4ba789e074e06ceddreed
6348b26b99c97473f020df4b9d4ba789e074e06ceddreedstatic void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMColor expected) {
6358b26b99c97473f020df4b9d4ba789e074e06ceddreed    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
6368b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkPMColor pixel;
6378b26b99c97473f020df4b9d4ba789e074e06ceddreed    REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0, 0));
6388b26b99c97473f020df4b9d4ba789e074e06ceddreed    REPORTER_ASSERT(reporter, pixel == expected);
6398b26b99c97473f020df4b9d4ba789e074e06ceddreed}
6408b26b99c97473f020df4b9d4ba789e074e06ceddreed
6418b26b99c97473f020df4b9d4ba789e074e06ceddreedDEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) {
6428b26b99c97473f020df4b9d4ba789e074e06ceddreed    GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType);
6438b26b99c97473f020df4b9d4ba789e074e06ceddreed    if (!ctx) {
6448b26b99c97473f020df4b9d4ba789e074e06ceddreed        REPORTER_ASSERT(reporter, false);
6458b26b99c97473f020df4b9d4ba789e074e06ceddreed        return;
6468b26b99c97473f020df4b9d4ba789e074e06ceddreed    }
6478b26b99c97473f020df4b9d4ba789e074e06ceddreed    GrTextureProvider* provider = ctx->textureProvider();
6488b26b99c97473f020df4b9d4ba789e074e06ceddreed
6498b26b99c97473f020df4b9d4ba789e074e06ceddreed    const int w = 10;
6508b26b99c97473f020df4b9d4ba789e074e06ceddreed    const int h = 10;
6518b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkPMColor storage[w * h];
6528b26b99c97473f020df4b9d4ba789e074e06ceddreed    const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED);
6538b26b99c97473f020df4b9d4ba789e074e06ceddreed    sk_memset32(storage, expected0, w * h);
6548b26b99c97473f020df4b9d4ba789e074e06ceddreed
6558b26b99c97473f020df4b9d4ba789e074e06ceddreed    GrSurfaceDesc desc;
6568b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fFlags = kRenderTarget_GrSurfaceFlag;  // needs to be a rendertarget for readpixels();
6578b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fOrigin = kDefault_GrSurfaceOrigin;
6588b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fWidth = w;
6598b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fHeight = h;
6608b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fConfig = kSkia8888_GrPixelConfig;
6618b26b99c97473f020df4b9d4ba789e074e06ceddreed    desc.fSampleCnt = 0;
6628b26b99c97473f020df4b9d4ba789e074e06ceddreed
6638b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w * 4));
6648b26b99c97473f020df4b9d4ba789e074e06ceddreed    if (!tex) {
6658b26b99c97473f020df4b9d4ba789e074e06ceddreed        REPORTER_ASSERT(reporter, false);
6668b26b99c97473f020df4b9d4ba789e074e06ceddreed        return;
6678b26b99c97473f020df4b9d4ba789e074e06ceddreed    }
6688b26b99c97473f020df4b9d4ba789e074e06ceddreed
6698b26b99c97473f020df4b9d4ba789e074e06ceddreed    GrBackendObject srcTex = tex->getTextureHandle();
6708b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, false));
6718b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, true));
6728b26b99c97473f020df4b9d4ba789e074e06ceddreed
6738b26b99c97473f020df4b9d4ba789e074e06ceddreed    test_image_color(reporter, refImg, expected0);
6748b26b99c97473f020df4b9d4ba789e074e06ceddreed    test_image_color(reporter, cpyImg, expected0);
6758b26b99c97473f020df4b9d4ba789e074e06ceddreed
6768b26b99c97473f020df4b9d4ba789e074e06ceddreed    // Now lets jam new colors into our "external" texture, and see if the images notice
6778b26b99c97473f020df4b9d4ba789e074e06ceddreed    const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE);
6788b26b99c97473f020df4b9d4ba789e074e06ceddreed    sk_memset32(storage, expected1, w * h);
6798b26b99c97473f020df4b9d4ba789e074e06ceddreed    tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kFlushWrites_PixelOp);
6808b26b99c97473f020df4b9d4ba789e074e06ceddreed
6818b26b99c97473f020df4b9d4ba789e074e06ceddreed    // We expect the ref'd image to see the new color, but cpy'd one should still see the old color
6828b26b99c97473f020df4b9d4ba789e074e06ceddreed    test_image_color(reporter, refImg, expected1);
6838b26b99c97473f020df4b9d4ba789e074e06ceddreed    test_image_color(reporter, cpyImg, expected0);
6848b26b99c97473f020df4b9d4ba789e074e06ceddreed}
6858b26b99c97473f020df4b9d4ba789e074e06ceddreed#endif
686