blob: da9268dded166a514e1d349b8b8209abe8fca1eb [file] [log] [blame]
reed871872f2015-06-22 12:48:26 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
bsalomon8e74f802016-01-30 10:01:40 -08008#include <functional>
bsalomon0d996862016-03-09 18:44:43 -08009#include <initializer_list>
bsalomon8e74f802016-01-30 10:01:40 -080010#include "DMGpuSupport.h"
11
robertphillips25058142016-03-16 09:47:08 -070012#include "SkAutoPixmapStorage.h"
halcanaryc56c6ef2015-09-28 11:55:28 -070013#include "SkBitmap.h"
reed871872f2015-06-22 12:48:26 -070014#include "SkCanvas.h"
15#include "SkData.h"
16#include "SkDevice.h"
17#include "SkImageEncoder.h"
kkinnunen7b94c142015-11-24 07:39:40 -080018#include "SkImageGenerator.h"
reed871872f2015-06-22 12:48:26 -070019#include "SkImage_Base.h"
fmalitac3470342015-09-04 11:36:39 -070020#include "SkPicture.h"
21#include "SkPictureRecorder.h"
fmalita2be71252015-09-03 07:17:25 -070022#include "SkPixelSerializer.h"
reed871872f2015-06-22 12:48:26 -070023#include "SkRRect.h"
fmalitac3470342015-09-04 11:36:39 -070024#include "SkStream.h"
reed871872f2015-06-22 12:48:26 -070025#include "SkSurface.h"
26#include "SkUtils.h"
27#include "Test.h"
28
reed871872f2015-06-22 12:48:26 -070029static void assert_equal(skiatest::Reporter* reporter, SkImage* a, const SkIRect* subsetA,
30 SkImage* b) {
31 const int widthA = subsetA ? subsetA->width() : a->width();
32 const int heightA = subsetA ? subsetA->height() : a->height();
33
34 REPORTER_ASSERT(reporter, widthA == b->width());
35 REPORTER_ASSERT(reporter, heightA == b->height());
reed1cb36462016-03-09 15:21:32 -080036
37 // see https://bug.skia.org/3965
38 //REPORTER_ASSERT(reporter, a->isOpaque() == b->isOpaque());
reed871872f2015-06-22 12:48:26 -070039
40 SkImageInfo info = SkImageInfo::MakeN32(widthA, heightA,
41 a->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
42 SkAutoPixmapStorage pmapA, pmapB;
43 pmapA.alloc(info);
44 pmapB.alloc(info);
45
46 const int srcX = subsetA ? subsetA->x() : 0;
47 const int srcY = subsetA ? subsetA->y() : 0;
48
49 REPORTER_ASSERT(reporter, a->readPixels(pmapA, srcX, srcY));
50 REPORTER_ASSERT(reporter, b->readPixels(pmapB, 0, 0));
51
52 const size_t widthBytes = widthA * info.bytesPerPixel();
53 for (int y = 0; y < heightA; ++y) {
54 REPORTER_ASSERT(reporter, !memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), widthBytes));
55 }
56}
kkinnunen7b94c142015-11-24 07:39:40 -080057static void draw_image_test_pattern(SkCanvas* canvas) {
reed871872f2015-06-22 12:48:26 -070058 canvas->clear(SK_ColorWHITE);
reed871872f2015-06-22 12:48:26 -070059 SkPaint paint;
60 paint.setColor(SK_ColorBLACK);
kkinnunen7b94c142015-11-24 07:39:40 -080061 canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
62}
63static SkImage* create_image() {
64 const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
65 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
66 draw_image_test_pattern(surface->getCanvas());
reed871872f2015-06-22 12:48:26 -070067 return surface->newImageSnapshot();
68}
bsalomon0d996862016-03-09 18:44:43 -080069static SkImage* create_image_565() {
70 const SkImageInfo info = SkImageInfo::Make(20, 20, kRGB_565_SkColorType, kOpaque_SkAlphaType);
71 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
72 draw_image_test_pattern(surface->getCanvas());
73 return surface->newImageSnapshot();
74}
bsalomon0d996862016-03-09 18:44:43 -080075static SkImage* create_image_ct() {
76 SkPMColor colors[] = {
77 SkPreMultiplyARGB(0xFF, 0xFF, 0xFF, 0x00),
78 SkPreMultiplyARGB(0x80, 0x00, 0xA0, 0xFF),
79 SkPreMultiplyARGB(0xFF, 0xBB, 0x00, 0xBB)
80 };
81 SkAutoTUnref<SkColorTable> colorTable(new SkColorTable(colors, SK_ARRAY_COUNT(colors)));
82 uint8_t data[] = {
83 0, 0, 0, 0, 0,
84 0, 1, 1, 1, 0,
85 0, 1, 2, 1, 0,
86 0, 1, 1, 1, 0,
87 0, 0, 0, 0, 0
88 };
89 SkImageInfo info = SkImageInfo::Make(5, 5, kIndex_8_SkColorType, kPremul_SkAlphaType);
90 return SkImage::NewRasterCopy(info, data, 5, colorTable);
91}
kkinnunen7b94c142015-11-24 07:39:40 -080092static SkData* create_image_data(SkImageInfo* info) {
93 *info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
94 const size_t rowBytes = info->minRowBytes();
95 SkAutoTUnref<SkData> data(SkData::NewUninitialized(rowBytes * info->height()));
96 {
97 SkBitmap bm;
98 bm.installPixels(*info, data->writable_data(), rowBytes);
99 SkCanvas canvas(bm);
100 draw_image_test_pattern(&canvas);
101 }
102 return data.release();
103}
104static SkImage* create_data_image() {
105 SkImageInfo info;
106 SkAutoTUnref<SkData> data(create_image_data(&info));
107 return SkImage::NewRasterData(info, data, info.minRowBytes());
108}
bsalomon8e74f802016-01-30 10:01:40 -0800109#if SK_SUPPORT_GPU // not gpu-specific but currently only used in GPU tests
110static SkImage* create_picture_image() {
111 SkPictureRecorder recorder;
112 SkCanvas* canvas = recorder.beginRecording(10, 10);
113 canvas->clear(SK_ColorCYAN);
114 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
115 return SkImage::NewFromPicture(picture, SkISize::Make(10, 10), nullptr, nullptr);
116};
117#endif
kkinnunen7b94c142015-11-24 07:39:40 -0800118// Want to ensure that our Release is called when the owning image is destroyed
119struct RasterDataHolder {
120 RasterDataHolder() : fReleaseCount(0) {}
121 SkAutoTUnref<SkData> fData;
122 int fReleaseCount;
123 static void Release(const void* pixels, void* context) {
124 RasterDataHolder* self = static_cast<RasterDataHolder*>(context);
125 self->fReleaseCount++;
126 self->fData.reset();
127 }
128};
129static SkImage* create_rasterproc_image(RasterDataHolder* dataHolder) {
130 SkASSERT(dataHolder);
131 SkImageInfo info;
132 SkAutoTUnref<SkData> data(create_image_data(&info));
133 dataHolder->fData.reset(SkRef(data.get()));
134 return SkImage::NewFromRaster(info, data->data(), info.minRowBytes(),
135 RasterDataHolder::Release, dataHolder);
136}
137static SkImage* create_codec_image() {
138 SkImageInfo info;
139 SkAutoTUnref<SkData> data(create_image_data(&info));
140 SkBitmap bitmap;
141 bitmap.installPixels(info, data->writable_data(), info.minRowBytes());
142 SkAutoTUnref<SkData> src(
143 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
144 return SkImage::NewFromEncoded(src);
145}
146#if SK_SUPPORT_GPU
147static SkImage* create_gpu_image(GrContext* context) {
148 const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
bsalomon5ec26ae2016-02-25 08:33:02 -0800149 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, SkBudgeted::kNo,
kkinnunen7b94c142015-11-24 07:39:40 -0800150 info));
151 draw_image_test_pattern(surface->getCanvas());
152 return surface->newImageSnapshot();
153}
154#endif
reed871872f2015-06-22 12:48:26 -0700155
kkinnunen7b94c142015-11-24 07:39:40 -0800156static void test_encode(skiatest::Reporter* reporter, SkImage* image) {
reed871872f2015-06-22 12:48:26 -0700157 const SkIRect ir = SkIRect::MakeXYWH(5, 5, 10, 10);
kkinnunen7b94c142015-11-24 07:39:40 -0800158 SkAutoTUnref<SkData> origEncoded(image->encode());
reed871872f2015-06-22 12:48:26 -0700159 REPORTER_ASSERT(reporter, origEncoded);
160 REPORTER_ASSERT(reporter, origEncoded->size() > 0);
161
162 SkAutoTUnref<SkImage> decoded(SkImage::NewFromEncoded(origEncoded));
163 REPORTER_ASSERT(reporter, decoded);
kkinnunen7b94c142015-11-24 07:39:40 -0800164 assert_equal(reporter, image, nullptr, decoded);
reed871872f2015-06-22 12:48:26 -0700165
166 // Now see if we can instantiate an image from a subset of the surface/origEncoded
mtklein5f939ab2016-03-16 10:28:35 -0700167
reed871872f2015-06-22 12:48:26 -0700168 decoded.reset(SkImage::NewFromEncoded(origEncoded, &ir));
169 REPORTER_ASSERT(reporter, decoded);
kkinnunen7b94c142015-11-24 07:39:40 -0800170 assert_equal(reporter, image, &ir, decoded);
reed871872f2015-06-22 12:48:26 -0700171}
172
kkinnunen7b94c142015-11-24 07:39:40 -0800173DEF_TEST(ImageEncode, reporter) {
174 SkAutoTUnref<SkImage> image(create_image());
175 test_encode(reporter, image);
reed871872f2015-06-22 12:48:26 -0700176}
177
178#if SK_SUPPORT_GPU
kkinnunen7b94c142015-11-24 07:39:40 -0800179DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageEncode_Gpu, reporter, context) {
180 SkAutoTUnref<SkImage> image(create_gpu_image(context));
181 test_encode(reporter, image);
reed871872f2015-06-22 12:48:26 -0700182}
183#endif
reed759373a2015-07-03 21:01:10 -0700184
fmalita2be71252015-09-03 07:17:25 -0700185namespace {
186
187const char* kSerializedData = "serialized";
188
189class MockSerializer : public SkPixelSerializer {
fmalitac3470342015-09-04 11:36:39 -0700190public:
191 MockSerializer(SkData* (*func)()) : fFunc(func), fDidEncode(false) { }
192
193 bool didEncode() const { return fDidEncode; }
194
fmalita2be71252015-09-03 07:17:25 -0700195protected:
reedc9e190d2015-09-28 09:58:41 -0700196 bool onUseEncodedData(const void*, size_t) override {
197 return false;
fmalita2be71252015-09-03 07:17:25 -0700198 }
199
halcanary99073712015-12-10 09:30:57 -0800200 SkData* onEncode(const SkPixmap&) override {
fmalitac3470342015-09-04 11:36:39 -0700201 fDidEncode = true;
202 return fFunc();
fmalita2be71252015-09-03 07:17:25 -0700203 }
fmalitac3470342015-09-04 11:36:39 -0700204
205private:
206 SkData* (*fFunc)();
207 bool fDidEncode;
208
209 typedef SkPixelSerializer INHERITED;
fmalita2be71252015-09-03 07:17:25 -0700210};
211
212} // anonymous namespace
213
214// Test that SkImage encoding observes custom pixel serializers.
215DEF_TEST(Image_Encode_Serializer, reporter) {
fmalitac3470342015-09-04 11:36:39 -0700216 MockSerializer serializer([]() -> SkData* { return SkData::NewWithCString(kSerializedData); });
kkinnunen7b94c142015-11-24 07:39:40 -0800217 SkAutoTUnref<SkImage> image(create_image());
fmalita2be71252015-09-03 07:17:25 -0700218 SkAutoTUnref<SkData> encoded(image->encode(&serializer));
219 SkAutoTUnref<SkData> reference(SkData::NewWithCString(kSerializedData));
220
fmalitac3470342015-09-04 11:36:39 -0700221 REPORTER_ASSERT(reporter, serializer.didEncode());
fmalita2be71252015-09-03 07:17:25 -0700222 REPORTER_ASSERT(reporter, encoded);
223 REPORTER_ASSERT(reporter, encoded->size() > 0);
224 REPORTER_ASSERT(reporter, encoded->equals(reference));
225}
226
fmalitac3470342015-09-04 11:36:39 -0700227// Test that image encoding failures do not break picture serialization/deserialization.
228DEF_TEST(Image_Serialize_Encoding_Failure, reporter) {
229 SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(100, 100));
230 surface->getCanvas()->clear(SK_ColorGREEN);
231 SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
232 REPORTER_ASSERT(reporter, image);
233
234 SkPictureRecorder recorder;
235 SkCanvas* canvas = recorder.beginRecording(100, 100);
236 canvas->drawImage(image, 0, 0);
237 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
238 REPORTER_ASSERT(reporter, picture);
239 REPORTER_ASSERT(reporter, picture->approximateOpCount() > 0);
240
241 MockSerializer emptySerializer([]() -> SkData* { return SkData::NewEmpty(); });
242 MockSerializer nullSerializer([]() -> SkData* { return nullptr; });
243 MockSerializer* serializers[] = { &emptySerializer, &nullSerializer };
244
245 for (size_t i = 0; i < SK_ARRAY_COUNT(serializers); ++i) {
246 SkDynamicMemoryWStream wstream;
247 REPORTER_ASSERT(reporter, !serializers[i]->didEncode());
248 picture->serialize(&wstream, serializers[i]);
249 REPORTER_ASSERT(reporter, serializers[i]->didEncode());
250
251 SkAutoTDelete<SkStream> rstream(wstream.detachAsStream());
252 SkAutoTUnref<SkPicture> deserialized(SkPicture::CreateFromStream(rstream));
253 REPORTER_ASSERT(reporter, deserialized);
254 REPORTER_ASSERT(reporter, deserialized->approximateOpCount() > 0);
255 }
256}
257
reed759373a2015-07-03 21:01:10 -0700258DEF_TEST(Image_NewRasterCopy, reporter) {
259 const SkPMColor red = SkPackARGB32(0xFF, 0xFF, 0, 0);
260 const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
261 const SkPMColor blue = SkPackARGB32(0xFF, 0, 0, 0xFF);
262 SkPMColor colors[] = { red, green, blue, 0 };
halcanary385fe4d2015-08-26 13:07:48 -0700263 SkAutoTUnref<SkColorTable> ctable(new SkColorTable(colors, SK_ARRAY_COUNT(colors)));
reed759373a2015-07-03 21:01:10 -0700264 // The colortable made a copy, so we can trash the original colors
265 memset(colors, 0xFF, sizeof(colors));
266
267 const SkImageInfo srcInfo = SkImageInfo::Make(2, 2, kIndex_8_SkColorType, kPremul_SkAlphaType);
268 const size_t srcRowBytes = 2 * sizeof(uint8_t);
269 uint8_t indices[] = { 0, 1, 2, 3 };
270 SkAutoTUnref<SkImage> image(SkImage::NewRasterCopy(srcInfo, indices, srcRowBytes, ctable));
271 // The image made a copy, so we can trash the original indices
272 memset(indices, 0xFF, sizeof(indices));
273
274 const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
275 const size_t dstRowBytes = 2 * sizeof(SkPMColor);
276 SkPMColor pixels[4];
277 memset(pixels, 0xFF, sizeof(pixels)); // init with values we don't expect
278 image->readPixels(dstInfo, pixels, dstRowBytes, 0, 0);
279 REPORTER_ASSERT(reporter, red == pixels[0]);
280 REPORTER_ASSERT(reporter, green == pixels[1]);
281 REPORTER_ASSERT(reporter, blue == pixels[2]);
282 REPORTER_ASSERT(reporter, 0 == pixels[3]);
283}
fmalita8c0144c2015-07-22 05:56:16 -0700284
285// Test that a draw that only partially covers the drawing surface isn't
286// interpreted as covering the entire drawing surface (i.e., exercise one of the
287// conditions of SkCanvas::wouldOverwriteEntireSurface()).
288DEF_TEST(Image_RetainSnapshot, reporter) {
289 const SkPMColor red = SkPackARGB32(0xFF, 0xFF, 0, 0);
290 const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
291 SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2);
292 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
293 surface->getCanvas()->clear(0xFF00FF00);
294
295 SkPMColor pixels[4];
296 memset(pixels, 0xFF, sizeof(pixels)); // init with values we don't expect
297 const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
298 const size_t dstRowBytes = 2 * sizeof(SkPMColor);
299
300 SkAutoTUnref<SkImage> image1(surface->newImageSnapshot());
301 REPORTER_ASSERT(reporter, image1->readPixels(dstInfo, pixels, dstRowBytes, 0, 0));
302 for (size_t i = 0; i < SK_ARRAY_COUNT(pixels); ++i) {
303 REPORTER_ASSERT(reporter, pixels[i] == green);
304 }
305
306 SkPaint paint;
307 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
308 paint.setColor(SK_ColorRED);
309
310 surface->getCanvas()->drawRect(SkRect::MakeXYWH(1, 1, 1, 1), paint);
311
312 SkAutoTUnref<SkImage> image2(surface->newImageSnapshot());
313 REPORTER_ASSERT(reporter, image2->readPixels(dstInfo, pixels, dstRowBytes, 0, 0));
314 REPORTER_ASSERT(reporter, pixels[0] == green);
315 REPORTER_ASSERT(reporter, pixels[1] == green);
316 REPORTER_ASSERT(reporter, pixels[2] == green);
317 REPORTER_ASSERT(reporter, pixels[3] == red);
318}
reed80c772b2015-07-30 18:58:23 -0700319
320/////////////////////////////////////////////////////////////////////////////////////////////////
reed80c772b2015-07-30 18:58:23 -0700321
322static void make_bitmap_mutable(SkBitmap* bm) {
323 bm->allocN32Pixels(10, 10);
324}
325
326static void make_bitmap_immutable(SkBitmap* bm) {
327 bm->allocN32Pixels(10, 10);
328 bm->setImmutable();
329}
330
331DEF_TEST(image_newfrombitmap, reporter) {
332 const struct {
333 void (*fMakeProc)(SkBitmap*);
334 bool fExpectPeekSuccess;
335 bool fExpectSharedID;
fmalitaddbbdda2015-08-20 08:47:26 -0700336 bool fExpectLazy;
reed80c772b2015-07-30 18:58:23 -0700337 } rec[] = {
fmalitaddbbdda2015-08-20 08:47:26 -0700338 { make_bitmap_mutable, true, false, false },
339 { make_bitmap_immutable, true, true, false },
reed80c772b2015-07-30 18:58:23 -0700340 };
341
342 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
343 SkBitmap bm;
344 rec[i].fMakeProc(&bm);
345
346 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bm));
347 SkPixmap pmap;
348
349 const bool sharedID = (image->uniqueID() == bm.getGenerationID());
350 REPORTER_ASSERT(reporter, sharedID == rec[i].fExpectSharedID);
351
reed80c772b2015-07-30 18:58:23 -0700352 const bool peekSuccess = image->peekPixels(&pmap);
353 REPORTER_ASSERT(reporter, peekSuccess == rec[i].fExpectPeekSuccess);
fmalitaddbbdda2015-08-20 08:47:26 -0700354
355 const bool lazy = image->isLazyGenerated();
356 REPORTER_ASSERT(reporter, lazy == rec[i].fExpectLazy);
reed80c772b2015-07-30 18:58:23 -0700357 }
358}
reed6f1216a2015-08-04 08:10:13 -0700359
360///////////////////////////////////////////////////////////////////////////////////////////////////
361#if SK_SUPPORT_GPU
362
reed6f1216a2015-08-04 08:10:13 -0700363#include "SkBitmapCache.h"
364
365/*
366 * This tests the caching (and preemptive purge) of the raster equivalent of a gpu-image.
367 * We cache it for performance when drawing into a raster surface.
368 *
369 * A cleaner test would know if each drawImage call triggered a read-back from the gpu,
370 * but we don't have that facility (at the moment) so we use a little internal knowledge
371 * of *how* the raster version is cached, and look for that.
372 */
kkinnunen7b94c142015-11-24 07:39:40 -0800373DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_Gpu2Cpu, reporter, context) {
374 SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
375 SkAutoTUnref<SkImage> image(create_gpu_image(context));
reed6f1216a2015-08-04 08:10:13 -0700376 const uint32_t uniqueID = image->uniqueID();
377
378 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
379
380 // now we can test drawing a gpu-backed image into a cpu-backed surface
381
382 {
383 SkBitmap cachedBitmap;
384 REPORTER_ASSERT(reporter, !SkBitmapCache::Find(uniqueID, &cachedBitmap));
385 }
386
387 surface->getCanvas()->drawImage(image, 0, 0);
388 {
389 SkBitmap cachedBitmap;
390 if (SkBitmapCache::Find(uniqueID, &cachedBitmap)) {
391 REPORTER_ASSERT(reporter, cachedBitmap.getGenerationID() == uniqueID);
392 REPORTER_ASSERT(reporter, cachedBitmap.isImmutable());
393 REPORTER_ASSERT(reporter, cachedBitmap.getPixels());
394 } else {
395 // unexpected, but not really a bug, since the cache is global and this test may be
396 // run w/ other threads competing for its budget.
397 SkDebugf("SkImage_Gpu2Cpu : cachedBitmap was already purged\n");
398 }
399 }
400
401 image.reset(nullptr);
402 {
403 SkBitmap cachedBitmap;
404 REPORTER_ASSERT(reporter, !SkBitmapCache::Find(uniqueID, &cachedBitmap));
405 }
406}
bsalomon8e74f802016-01-30 10:01:40 -0800407
408DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_newTextureImage, reporter, context, glContext) {
409 GrContextFactory otherFactory;
410 GrContextFactory::ContextInfo otherContextInfo =
411 otherFactory.getContextInfo(GrContextFactory::kNative_GLContextType);
412 glContext->makeCurrent();
413
414 std::function<SkImage*()> imageFactories[] = {
415 create_image,
416 create_codec_image,
417 create_data_image,
418 // Create an image from a picture.
419 create_picture_image,
420 // Create a texture image.
421 [context] { return create_gpu_image(context); },
422 // Create a texture image in a another GrContext.
423 [glContext, otherContextInfo] {
424 otherContextInfo.fGLContext->makeCurrent();
425 SkImage* otherContextImage = create_gpu_image(otherContextInfo.fGrContext);
426 glContext->makeCurrent();
427 return otherContextImage;
428 }
429 };
430
431 for (auto factory : imageFactories) {
432 SkAutoTUnref<SkImage> image(factory());
433 if (!image) {
434 ERRORF(reporter, "Error creating image.");
435 continue;
436 }
437 GrTexture* origTexture = as_IB(image)->peekTexture();
438
439 SkAutoTUnref<SkImage> texImage(image->newTextureImage(context));
440 if (!texImage) {
441 // We execpt to fail if image comes from a different GrContext.
442 if (!origTexture || origTexture->getContext() == context) {
443 ERRORF(reporter, "newTextureImage failed.");
444 }
445 continue;
446 }
447 GrTexture* copyTexture = as_IB(texImage)->peekTexture();
448 if (!copyTexture) {
449 ERRORF(reporter, "newTextureImage returned non-texture image.");
450 continue;
451 }
452 if (origTexture) {
453 if (origTexture != copyTexture) {
454 ERRORF(reporter, "newTextureImage made unnecessary texture copy.");
455 }
456 }
457 if (image->width() != texImage->width() || image->height() != texImage->height()) {
458 ERRORF(reporter, "newTextureImage changed the image size.");
459 }
460 if (image->isOpaque() != texImage->isOpaque()) {
461 ERRORF(reporter, "newTextureImage changed image opaqueness.");
462 }
463 }
464}
reed6f1216a2015-08-04 08:10:13 -0700465#endif
halcanaryc56c6ef2015-09-28 11:55:28 -0700466
halcanary6950de62015-11-07 05:29:00 -0800467// https://bug.skia.org/4390
halcanaryc56c6ef2015-09-28 11:55:28 -0700468DEF_TEST(ImageFromIndex8Bitmap, r) {
469 SkPMColor pmColors[1] = {SkPreMultiplyColor(SK_ColorWHITE)};
470 SkBitmap bm;
471 SkAutoTUnref<SkColorTable> ctable(
472 new SkColorTable(pmColors, SK_ARRAY_COUNT(pmColors)));
473 SkImageInfo info =
474 SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType);
475 bm.allocPixels(info, nullptr, ctable);
476 SkAutoLockPixels autoLockPixels(bm);
477 *bm.getAddr8(0, 0) = 0;
478 SkAutoTUnref<SkImage> img(SkImage::NewFromBitmap(bm));
479 REPORTER_ASSERT(r, img.get() != nullptr);
480}
kkinnunen4e184132015-11-17 22:53:28 -0800481
kkinnunen4e184132015-11-17 22:53:28 -0800482class EmptyGenerator : public SkImageGenerator {
483public:
484 EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
485};
486
kkinnunen7b94c142015-11-24 07:39:40 -0800487DEF_TEST(ImageEmpty, reporter) {
kkinnunen4e184132015-11-17 22:53:28 -0800488 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
kkinnunen4e184132015-11-17 22:53:28 -0800489 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterCopy(info, nullptr, 0));
490 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterData(info, nullptr, 0));
491 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromRaster(info, nullptr, 0, nullptr, nullptr));
492 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromGenerator(new EmptyGenerator));
493}
494
kkinnunen7b94c142015-11-24 07:39:40 -0800495DEF_TEST(ImageDataRef, reporter) {
kkinnunen4e184132015-11-17 22:53:28 -0800496 SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
497 size_t rowBytes = info.minRowBytes();
498 size_t size = info.getSafeSize(rowBytes);
499 SkData* data = SkData::NewUninitialized(size);
kkinnunen4e184132015-11-17 22:53:28 -0800500 REPORTER_ASSERT(reporter, data->unique());
501 SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
502 REPORTER_ASSERT(reporter, !data->unique());
503 image->unref();
504 REPORTER_ASSERT(reporter, data->unique());
505 data->unref();
506}
507
kkinnunen4e184132015-11-17 22:53:28 -0800508static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
509 for (int i = 0; i < count; ++i) {
510 if (pixels[i] != expected) {
511 return false;
512 }
513 }
514 return true;
515}
516
kkinnunen7b94c142015-11-24 07:39:40 -0800517static void test_read_pixels(skiatest::Reporter* reporter, SkImage* image) {
518 const SkPMColor expected = SkPreMultiplyColor(SK_ColorWHITE);
kkinnunen4e184132015-11-17 22:53:28 -0800519 const SkPMColor notExpected = ~expected;
520
521 const int w = 2, h = 2;
522 const size_t rowBytes = w * sizeof(SkPMColor);
523 SkPMColor pixels[w*h];
524
525 SkImageInfo info;
526
527 info = SkImageInfo::MakeUnknown(w, h);
528 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
529
530 // out-of-bounds should fail
531 info = SkImageInfo::MakeN32Premul(w, h);
532 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
533 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
534 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
535 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
536
537 // top-left should succeed
kkinnunen7b94c142015-11-24 07:39:40 -0800538 sk_memset32(pixels, notExpected, w*h);
kkinnunen4e184132015-11-17 22:53:28 -0800539 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
540 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
541
542 // bottom-right should succeed
kkinnunen7b94c142015-11-24 07:39:40 -0800543 sk_memset32(pixels, notExpected, w*h);
kkinnunen4e184132015-11-17 22:53:28 -0800544 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
545 image->width() - w, image->height() - h));
546 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
547
548 // partial top-left should succeed
kkinnunen7b94c142015-11-24 07:39:40 -0800549 sk_memset32(pixels, notExpected, w*h);
kkinnunen4e184132015-11-17 22:53:28 -0800550 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
551 REPORTER_ASSERT(reporter, pixels[3] == expected);
552 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
553
554 // partial bottom-right should succeed
kkinnunen7b94c142015-11-24 07:39:40 -0800555 sk_memset32(pixels, notExpected, w*h);
kkinnunen4e184132015-11-17 22:53:28 -0800556 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
557 image->width() - 1, image->height() - 1));
558 REPORTER_ASSERT(reporter, pixels[0] == expected);
559 REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
560}
kkinnunen7b94c142015-11-24 07:39:40 -0800561DEF_TEST(ImageReadPixels, reporter) {
562 SkAutoTUnref<SkImage> image(create_image());
563 test_read_pixels(reporter, image);
564
565 image.reset(create_data_image());
566 test_read_pixels(reporter, image);
567
568 RasterDataHolder dataHolder;
569 image.reset(create_rasterproc_image(&dataHolder));
570 test_read_pixels(reporter, image);
571 image.reset();
572 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
573
574 image.reset(create_codec_image());
575 test_read_pixels(reporter, image);
576}
577#if SK_SUPPORT_GPU
578DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageReadPixels_Gpu, reporter, context) {
579 SkAutoTUnref<SkImage> image(create_gpu_image(context));
580 test_read_pixels(reporter, image);
581}
582#endif
kkinnunen4e184132015-11-17 22:53:28 -0800583
584static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image,
585 const SkBitmap& bitmap, SkImage::LegacyBitmapMode mode) {
586 REPORTER_ASSERT(reporter, image->width() == bitmap.width());
587 REPORTER_ASSERT(reporter, image->height() == bitmap.height());
588 REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque());
589
590 if (SkImage::kRO_LegacyBitmapMode == mode) {
591 REPORTER_ASSERT(reporter, bitmap.isImmutable());
592 }
593
594 SkAutoLockPixels alp(bitmap);
595 REPORTER_ASSERT(reporter, bitmap.getPixels());
596
597 const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
598 SkPMColor imageColor;
599 REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMColor), 0, 0));
600 REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
601}
602
kkinnunen7b94c142015-11-24 07:39:40 -0800603static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image, SkImage::LegacyBitmapMode mode) {
604 SkBitmap bitmap;
605 REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, mode));
606 check_legacy_bitmap(reporter, image, bitmap, mode);
607
608 // Test subsetting to exercise the rowBytes logic.
609 SkBitmap tmp;
610 REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(image->width() / 2,
611 image->height() / 2)));
612 SkAutoTUnref<SkImage> subsetImage(SkImage::NewFromBitmap(tmp));
613 REPORTER_ASSERT(reporter, subsetImage);
614
615 SkBitmap subsetBitmap;
616 REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, mode));
617 check_legacy_bitmap(reporter, subsetImage, subsetBitmap, mode);
618}
619DEF_TEST(ImageLegacyBitmap, reporter) {
kkinnunen4e184132015-11-17 22:53:28 -0800620 const SkImage::LegacyBitmapMode modes[] = {
621 SkImage::kRO_LegacyBitmapMode,
622 SkImage::kRW_LegacyBitmapMode,
623 };
kkinnunen7b94c142015-11-24 07:39:40 -0800624 for (auto& mode : modes) {
625 SkAutoTUnref<SkImage> image(create_image());
626 test_legacy_bitmap(reporter, image, mode);
kkinnunen4e184132015-11-17 22:53:28 -0800627
kkinnunen7b94c142015-11-24 07:39:40 -0800628 image.reset(create_data_image());
629 test_legacy_bitmap(reporter, image, mode);
kkinnunen4e184132015-11-17 22:53:28 -0800630
kkinnunen7b94c142015-11-24 07:39:40 -0800631 RasterDataHolder dataHolder;
632 image.reset(create_rasterproc_image(&dataHolder));
633 test_legacy_bitmap(reporter, image, mode);
634 image.reset();
635 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
636
637 image.reset(create_codec_image());
638 test_legacy_bitmap(reporter, image, mode);
kkinnunen4e184132015-11-17 22:53:28 -0800639 }
640}
kkinnunen4e184132015-11-17 22:53:28 -0800641#if SK_SUPPORT_GPU
kkinnunen7b94c142015-11-24 07:39:40 -0800642DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageLegacyBitmap_Gpu, reporter, context) {
643 const SkImage::LegacyBitmapMode modes[] = {
644 SkImage::kRO_LegacyBitmapMode,
645 SkImage::kRW_LegacyBitmapMode,
646 };
647 for (auto& mode : modes) {
648 SkAutoTUnref<SkImage> image(create_gpu_image(context));
649 test_legacy_bitmap(reporter, image, mode);
kkinnunen4e184132015-11-17 22:53:28 -0800650 }
kkinnunen7b94c142015-11-24 07:39:40 -0800651}
kkinnunen4e184132015-11-17 22:53:28 -0800652#endif
653
kkinnunen7b94c142015-11-24 07:39:40 -0800654static void test_peek(skiatest::Reporter* reporter, SkImage* image, bool expectPeekSuccess) {
reed6ceeebd2016-03-09 14:26:26 -0800655 SkPixmap pm;
656 bool success = image->peekPixels(&pm);
kkinnunen7b94c142015-11-24 07:39:40 -0800657 REPORTER_ASSERT(reporter, expectPeekSuccess == success);
658 if (success) {
reed6ceeebd2016-03-09 14:26:26 -0800659 const SkImageInfo& info = pm.info();
kkinnunen7b94c142015-11-24 07:39:40 -0800660 REPORTER_ASSERT(reporter, 20 == info.width());
661 REPORTER_ASSERT(reporter, 20 == info.height());
662 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
663 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
664 kOpaque_SkAlphaType == info.alphaType());
reed6ceeebd2016-03-09 14:26:26 -0800665 REPORTER_ASSERT(reporter, info.minRowBytes() <= pm.rowBytes());
666 REPORTER_ASSERT(reporter, SkPreMultiplyColor(SK_ColorWHITE) == *pm.addr32(0, 0));
kkinnunen4e184132015-11-17 22:53:28 -0800667 }
kkinnunen7b94c142015-11-24 07:39:40 -0800668}
669DEF_TEST(ImagePeek, reporter) {
670 SkAutoTUnref<SkImage> image(create_image());
671 test_peek(reporter, image, true);
672
673 image.reset(create_data_image());
674 test_peek(reporter, image, true);
675
676 RasterDataHolder dataHolder;
677 image.reset(create_rasterproc_image(&dataHolder));
678 test_peek(reporter, image, true);
679 image.reset();
680 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
681
682 image.reset(create_codec_image());
683 test_peek(reporter, image, false);
kkinnunen4e184132015-11-17 22:53:28 -0800684}
685#if SK_SUPPORT_GPU
kkinnunen7b94c142015-11-24 07:39:40 -0800686DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImagePeek_Gpu, reporter, context) {
687 SkAutoTUnref<SkImage> image(create_gpu_image(context));
688 test_peek(reporter, image, false);
689}
690#endif
kkinnunen4e184132015-11-17 22:53:28 -0800691
kkinnunen7b94c142015-11-24 07:39:40 -0800692#if SK_SUPPORT_GPU
693struct TextureReleaseChecker {
694 TextureReleaseChecker() : fReleaseCount(0) {}
695 int fReleaseCount;
696 static void Release(void* self) {
697 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
kkinnunen4e184132015-11-17 22:53:28 -0800698 }
699};
kkinnunen7b94c142015-11-24 07:39:40 -0800700static void check_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMColor expected) {
kkinnunen4e184132015-11-17 22:53:28 -0800701 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
702 SkPMColor pixel;
703 REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0, 0));
704 REPORTER_ASSERT(reporter, pixel == expected);
705}
kkinnunen7b94c142015-11-24 07:39:40 -0800706DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_NewFromTexture, reporter, context) {
707 GrTextureProvider* provider = context->textureProvider();
kkinnunen4e184132015-11-17 22:53:28 -0800708 const int w = 10;
709 const int h = 10;
710 SkPMColor storage[w * h];
711 const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED);
712 sk_memset32(storage, expected0, w * h);
kkinnunen4e184132015-11-17 22:53:28 -0800713 GrSurfaceDesc desc;
714 desc.fFlags = kRenderTarget_GrSurfaceFlag; // needs to be a rendertarget for readpixels();
715 desc.fOrigin = kDefault_GrSurfaceOrigin;
716 desc.fWidth = w;
717 desc.fHeight = h;
718 desc.fConfig = kSkia8888_GrPixelConfig;
719 desc.fSampleCnt = 0;
bsalomon5ec26ae2016-02-25 08:33:02 -0800720 SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, SkBudgeted::kNo, storage, w * 4));
kkinnunen4e184132015-11-17 22:53:28 -0800721 if (!tex) {
722 REPORTER_ASSERT(reporter, false);
723 return;
724 }
725
kkinnunen7b94c142015-11-24 07:39:40 -0800726 GrBackendTextureDesc backendDesc;
727 backendDesc.fConfig = kSkia8888_GrPixelConfig;
728 backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
729 backendDesc.fWidth = w;
730 backendDesc.fHeight = h;
731 backendDesc.fSampleCnt = 0;
732 backendDesc.fTextureHandle = tex->getTextureHandle();
733 TextureReleaseChecker releaseChecker;
734 SkAutoTUnref<SkImage> refImg(
735 SkImage::NewFromTexture(context, backendDesc, kPremul_SkAlphaType,
736 TextureReleaseChecker::Release, &releaseChecker));
737 SkAutoTUnref<SkImage> cpyImg(SkImage::NewFromTextureCopy(context, backendDesc,
738 kPremul_SkAlphaType));
kkinnunen4e184132015-11-17 22:53:28 -0800739
kkinnunen7b94c142015-11-24 07:39:40 -0800740 check_image_color(reporter, refImg, expected0);
741 check_image_color(reporter, cpyImg, expected0);
kkinnunen4e184132015-11-17 22:53:28 -0800742
743 // Now lets jam new colors into our "external" texture, and see if the images notice
744 const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE);
745 sk_memset32(storage, expected1, w * h);
746 tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kFlushWrites_PixelOp);
747
748 // The cpy'd one should still see the old color
749#if 0
750 // There is no guarantee that refImg sees the new color. We are free to have made a copy. Our
751 // write pixels call violated the contract with refImg and refImg is now undefined.
kkinnunen7b94c142015-11-24 07:39:40 -0800752 check_image_color(reporter, refImg, expected1);
kkinnunen4e184132015-11-17 22:53:28 -0800753#endif
kkinnunen7b94c142015-11-24 07:39:40 -0800754 check_image_color(reporter, cpyImg, expected0);
kkinnunen4e184132015-11-17 22:53:28 -0800755
756 // Now exercise the release proc
kkinnunen7b94c142015-11-24 07:39:40 -0800757 REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
kkinnunen4e184132015-11-17 22:53:28 -0800758 refImg.reset(nullptr); // force a release of the image
kkinnunen7b94c142015-11-24 07:39:40 -0800759 REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
kkinnunen4e184132015-11-17 22:53:28 -0800760}
bsalomon0d996862016-03-09 18:44:43 -0800761
762static void check_images_same(skiatest::Reporter* reporter, const SkImage* a, const SkImage* b) {
763 if (a->width() != b->width() || a->height() != b->height()) {
764 ERRORF(reporter, "Images must have the same size");
765 return;
766 }
767 if (a->isOpaque() != b->isOpaque()) {
768 ERRORF(reporter, "Images must have the same opaquness");
769 return;
770 }
771
772 SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height());
773 SkAutoPixmapStorage apm;
774 SkAutoPixmapStorage bpm;
775
776 apm.alloc(info);
777 bpm.alloc(info);
778
779 if (!a->readPixels(apm, 0, 0)) {
780 ERRORF(reporter, "Could not read image a's pixels");
781 return;
782 }
783 if (!b->readPixels(bpm, 0, 0)) {
784 ERRORF(reporter, "Could not read image b's pixels");
785 return;
786 }
787
788 for (auto y = 0; y < info.height(); ++y) {
789 for (auto x = 0; x < info.width(); ++x) {
790 uint32_t pixelA = *apm.addr32(x, y);
791 uint32_t pixelB = *bpm.addr32(x, y);
792 if (pixelA != pixelB) {
793 ERRORF(reporter, "Expected image pixels to be the same. At %d,%d 0x%08x != 0x%08x",
794 x, y, pixelA, pixelB);
795 return;
796 }
797 }
798 }
799}
800
801DEF_GPUTEST_FOR_RENDERING_CONTEXTS(NewTextureFromPixmap, reporter, context) {
bsalomone6d665e2016-03-10 07:22:25 -0800802 for (auto create : {&create_image,
803 &create_image_565,
804 &create_image_ct}) {
bsalomon0d996862016-03-09 18:44:43 -0800805 SkAutoTUnref<SkImage> image((*create)());
806 if (!image) {
807 ERRORF(reporter, "Could not create image");
808 return;
809 }
810
811 SkPixmap pixmap;
812 if (!image->peekPixels(&pixmap)) {
813 ERRORF(reporter, "peek failed");
814 } else {
815 SkAutoTUnref<SkImage> texImage(SkImage::NewTextureFromPixmap(context, pixmap,
816 SkBudgeted::kNo));
817 if (!texImage) {
818 ERRORF(reporter, "NewTextureFromPixmap failed.");
819 } else {
820 check_images_same(reporter, image, texImage);
821 }
822 }
823 }
824}
825
bsalomon41b952c2016-03-11 06:46:33 -0800826DEF_GPUTEST_FOR_NATIVE_CONTEXT(DeferredTextureImage, reporter, context, glContext) {
827 SkAutoTUnref<GrContextThreadSafeProxy> proxy(context->threadSafeProxy());
828
829 GrContextFactory otherFactory;
830 GrContextFactory::ContextInfo otherContextInfo =
831 otherFactory.getContextInfo(GrContextFactory::kNative_GLContextType);
832
833 glContext->makeCurrent();
834 REPORTER_ASSERT(reporter, proxy);
835 struct {
836 std::function<SkImage *()> fImageFactory;
837 bool fExpectation;
838 } testCases[] = {
839 { create_image, true },
840 { create_codec_image, true },
841 { create_data_image, true },
842 { create_picture_image, false },
843 { [context] { return create_gpu_image(context); }, false },
844 // Create a texture image in a another GrContext.
845 { [glContext, otherContextInfo] {
846 otherContextInfo.fGLContext->makeCurrent();
847 SkImage *otherContextImage = create_gpu_image(otherContextInfo.fGrContext);
848 glContext->makeCurrent();
849 return otherContextImage;
850 }, false },
851 };
852
853
854 for (auto testCase : testCases) {
855 SkAutoTUnref<SkImage> image(testCase.fImageFactory());
856
857 // This isn't currently used in the implementation, just set any old values.
858 SkImage::DeferredTextureImageUsageParams params;
859 params.fQuality = kLow_SkFilterQuality;
860 params.fMatrix = SkMatrix::I();
861
862 size_t size = image->getDeferredTextureImageData(*proxy, &params, 1, nullptr);
863
864 static const char *const kFS[] = { "fail", "succeed" };
865 if (SkToBool(size) != testCase.fExpectation) {
866 ERRORF(reporter, "This image was expected to %s but did not.",
867 kFS[testCase.fExpectation]);
868 }
869 if (size) {
870 void* buffer = sk_malloc_throw(size);
871 void* misaligned = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(buffer) + 3);
872 if (image->getDeferredTextureImageData(*proxy, &params, 1, misaligned)) {
873 ERRORF(reporter, "Should fail when buffer is misaligned.");
874 }
875 if (!image->getDeferredTextureImageData(*proxy, &params, 1, buffer)) {
876 ERRORF(reporter, "deferred image size succeeded but creation failed.");
877 } else {
878 for (auto budgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) {
879 SkAutoTUnref<SkImage> newImage(
880 SkImage::NewFromDeferredTextureImageData(context, buffer, budgeted));
mtklein5f939ab2016-03-16 10:28:35 -0700881 REPORTER_ASSERT(reporter, newImage != nullptr);
bsalomon41b952c2016-03-11 06:46:33 -0800882 if (newImage) {
883 check_images_same(reporter, image, newImage);
884 }
885 // The other context should not be able to create images from texture data
886 // created by the original context.
887 SkAutoTUnref<SkImage> newImage2(SkImage::NewFromDeferredTextureImageData(
888 otherContextInfo.fGrContext, buffer, budgeted));
889 REPORTER_ASSERT(reporter, !newImage2);
890 glContext->makeCurrent();
891 }
892 }
893 sk_free(buffer);
894 }
895 }
896}
kkinnunen4e184132015-11-17 22:53:28 -0800897#endif