Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions
ImageTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageGenerator.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSerialProcs.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/encode/SkPngEncoder.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkCPUTypes.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrImageContext.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "modules/skcms/skcms.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkBitmapCache.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkMemset.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrImageContextPriv.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/image/GrImageUtils.h"
#include "src/gpu/ganesh/image/SkImage_GaneshYUVA.h"
#include "src/image/SkImageGeneratorPriv.h"
#include "src/image/SkImage_Base.h"
#include "src/shaders/SkImageShader.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/FenceSync.h"
#include "tools/gpu/ManagedBackendTexture.h"
#include "tools/gpu/ProxyUtils.h"
#include "tools/gpu/TestContext.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <functional>
#include <initializer_list>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>

Go to the source code of this file.

Classes

struct  RasterDataHolder
 
class  EmptyGenerator
 
struct  TextureReleaseChecker
 

Functions

SkImageInfo read_pixels_info (SkImage *image)
 
static void assert_equal (skiatest::Reporter *reporter, GrDirectContext *dContextA, SkImage *a, const SkIRect *subsetA, SkImage *b)
 
static void draw_image_test_pattern (SkCanvas *canvas)
 
static sk_sp< SkImagecreate_image ()
 
static sk_sp< SkDatacreate_image_data (SkImageInfo *info)
 
static sk_sp< SkImagecreate_data_image ()
 
static sk_sp< SkImagecreate_image_large (int maxTextureSize)
 
static sk_sp< SkImagecreate_picture_image ()
 
static sk_sp< SkImagecreate_rasterproc_image (RasterDataHolder *dataHolder)
 
static sk_sp< SkImagecreate_codec_image ()
 
static sk_sp< SkImagecreate_gpu_image (GrRecordingContext *rContext, bool withMips=false, skgpu::Budgeted budgeted=skgpu::Budgeted::kYes)
 
static void test_encode (skiatest::Reporter *reporter, GrDirectContext *dContext, SkImage *image)
 
 DEF_TEST (ImageEncode, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImageEncode_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_TEST (Image_MakeFromRasterBitmap, reporter)
 
 DEF_TEST (Image_Serialize_Encoding_Failure, reporter)
 
 DEF_TEST (Image_RetainSnapshot, reporter)
 
static void make_bitmap_mutable (SkBitmap *bm)
 
static void make_bitmap_immutable (SkBitmap *bm)
 
 DEF_TEST (image_newfrombitmap, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (SkImage_Ganesh2Cpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (SkImage_makeTextureImage, reporter, contextInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (SkImage_makeNonTextureImage, reporter, contextInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (GrContext_colorTypeSupportedAsImage, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (UnpremulTextureImage, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST (AbandonedContextImage, reporter, options, CtsEnforcement::kApiLevel_T)
 
 DEF_TEST (ImageEmpty, reporter)
 
 DEF_TEST (ImageDataRef, reporter)
 
static bool has_pixels (const SkPMColor pixels[], int count, SkPMColor expected)
 
static void image_test_read_pixels (GrDirectContext *dContext, skiatest::Reporter *reporter, SkImage *image)
 
 DEF_TEST (ImageReadPixels, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImageReadPixels_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
static void check_legacy_bitmap (skiatest::Reporter *reporter, GrDirectContext *dContext, const SkImage *image, const SkBitmap &bitmap)
 
static void test_legacy_bitmap (skiatest::Reporter *reporter, GrDirectContext *dContext, const SkImage *image)
 
 DEF_TEST (ImageLegacyBitmap, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImageLegacyBitmap_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
static void test_peek (skiatest::Reporter *reporter, SkImage *image, bool expectPeekSuccess)
 
 DEF_TEST (ImagePeek, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImagePeek_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_GL_CONTEXT (SkImage_NewFromTextureRelease, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
static void test_cross_context_image (skiatest::Reporter *reporter, const GrContextOptions &options, const char *testName, const std::function< sk_sp< SkImage >(GrDirectContext *)> &imageMaker)
 
 DEF_GANESH_TEST (SkImage_MakeCrossContextFromPixmapRelease, reporter, options, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST (SkImage_CrossContextGrayAlphaConfigs, reporter, options, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_GL_CONTEXT (makeBackendTexture, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImageBackendAccessAbandoned_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
static sk_sp< SkImagecreate_picture_image (sk_sp< SkColorSpace > space)
 
 DEF_TEST (Image_ColorSpace, r)
 
 DEF_TEST (Image_makeColorSpace, r)
 
static void make_all_premul (SkBitmap *bm)
 
static bool equal (const SkBitmap &a, const SkBitmap &b)
 
 DEF_TEST (image_roundtrip_encode, reporter)
 
 DEF_TEST (image_roundtrip_premul, reporter)
 
 DEF_TEST (image_from_encoded_alphatype_override, reporter)
 
static void check_scaled_pixels (skiatest::Reporter *reporter, SkPixmap *pmap, uint32_t expected)
 
static void test_scale_pixels (skiatest::Reporter *reporter, const SkImage *image, uint32_t expected)
 
 DEF_TEST (ImageScalePixels, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (ImageScalePixels_Gpu, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
static sk_sp< SkImageany_image_will_do ()
 
 DEF_TEST (Image_nonfinite_dst, reporter)
 
static sk_sp< SkImagemake_yuva_image (GrDirectContext *dContext)
 
 DEF_GANESH_TEST_FOR_ALL_CONTEXTS (ImageFlush, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
constexpr SkM44 gCentripetalCatmulRom (0.0f/2, -1.0f/2, 2.0f/2, -1.0f/2, 2.0f/2, 0.0f/2, -5.0f/2, 3.0f/2, 0.0f/2, 1.0f/2, 4.0f/2, -3.0f/2, 0.0f/2, 0.0f/2, -1.0f/2, 1.0f/2)
 
constexpr SkM44 gMitchellNetravali (1.0f/18, -9.0f/18, 15.0f/18, -7.0f/18, 16.0f/18, 0.0f/18, -36.0f/18, 21.0f/18, 1.0f/18, 9.0f/18, 27.0f/18, -21.0f/18, 0.0f/18, 0.0f/18, -6.0f/18, 7.0f/18)
 
 DEF_TEST (image_cubicresampler, reporter)
 
 DEF_TEST (image_subset_encode_skbug_7752, reporter)
 

Function Documentation

◆ any_image_will_do()

static sk_sp< SkImage > any_image_will_do ( )
static

Definition at line 1520 of file ImageTest.cpp.

1520 {
1521 return ToolUtils::GetResourceAsImage("images/mandrill_32.png");
1522}
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition DecodeUtils.h:25

◆ assert_equal()

static void assert_equal ( skiatest::Reporter reporter,
GrDirectContext dContextA,
SkImage a,
const SkIRect subsetA,
SkImage b 
)
static

Definition at line 107 of file ImageTest.cpp.

108 {
109 const int widthA = subsetA ? subsetA->width() : a->width();
110 const int heightA = subsetA ? subsetA->height() : a->height();
111
112 REPORTER_ASSERT(reporter, widthA == b->width());
113 REPORTER_ASSERT(reporter, heightA == b->height());
114
115 // see https://bug.skia.org/3965
116 //REPORTER_ASSERT(reporter, a->isOpaque() == b->isOpaque());
117
118 SkAutoPixmapStorage pmapA, pmapB;
119 pmapA.alloc(read_pixels_info(a));
120 pmapB.alloc(read_pixels_info(b));
121
122 const int srcX = subsetA ? subsetA->x() : 0;
123 const int srcY = subsetA ? subsetA->y() : 0;
124
125 REPORTER_ASSERT(reporter, a->readPixels(dContextA, pmapA, srcX, srcY));
126 REPORTER_ASSERT(reporter, b->readPixels(nullptr, pmapB, 0, 0));
127
128 const size_t widthBytes = widthA * 4;
129 for (int y = 0; y < heightA; ++y) {
130 REPORTER_ASSERT(reporter, !memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), widthBytes));
131 }
132}
reporter
SkImageInfo read_pixels_info(SkImage *image)
Definition ImageTest.cpp:98
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:280
void alloc(const SkImageInfo &)
const uint32_t * addr32() const
Definition SkPixmap.h:352
static bool b
struct MyStruct a[10]
double y
constexpr int32_t x() const
Definition SkRect.h:141
constexpr int32_t y() const
Definition SkRect.h:148
constexpr int32_t height() const
Definition SkRect.h:165
constexpr int32_t width() const
Definition SkRect.h:158

◆ check_legacy_bitmap()

static void check_legacy_bitmap ( skiatest::Reporter reporter,
GrDirectContext dContext,
const SkImage image,
const SkBitmap bitmap 
)
static

Definition at line 819 of file ImageTest.cpp.

820 {
821 REPORTER_ASSERT(reporter, image->width() == bitmap.width());
822 REPORTER_ASSERT(reporter, image->height() == bitmap.height());
823 REPORTER_ASSERT(reporter, image->alphaType() == bitmap.alphaType());
824
825 REPORTER_ASSERT(reporter, bitmap.isImmutable());
826
827 REPORTER_ASSERT(reporter, bitmap.getPixels());
828
829 const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
830 SkPMColor imageColor;
831 REPORTER_ASSERT(reporter, image->readPixels(dContext, info, &imageColor, sizeof(SkPMColor),
832 0, 0));
833 REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
834}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
uint32_t SkPMColor
Definition SkColor.h:205
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition SkImage.cpp:42
SkAlphaType alphaType() const
Definition SkImage.cpp:145
int width() const
Definition SkImage.h:283
int height() const
Definition SkImage.h:289
sk_sp< SkImage > image
Definition examples.cpp:29
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)

◆ check_scaled_pixels()

static void check_scaled_pixels ( skiatest::Reporter reporter,
SkPixmap pmap,
uint32_t  expected 
)
static

Definition at line 1457 of file ImageTest.cpp.

1457 {
1458 // Verify that all pixels contain the original test color
1459 for (auto y = 0; y < pmap->height(); ++y) {
1460 for (auto x = 0; x < pmap->width(); ++x) {
1461 uint32_t pixel = *pmap->addr32(x, y);
1462 if (pixel != expected) {
1463 ERRORF(reporter, "Expected scaled pixels to be the same. At %d,%d 0x%08x != 0x%08x",
1464 x, y, pixel, expected);
1465 return;
1466 }
1467 }
1468 }
1469}
#define ERRORF(r,...)
Definition Test.h:287
int width() const
Definition SkPixmap.h:160
int height() const
Definition SkPixmap.h:166
double x

◆ create_codec_image()

static sk_sp< SkImage > create_codec_image ( )
static

Definition at line 201 of file ImageTest.cpp.

201 {
205 bitmap.installPixels(info, data->writable_data(), info.minRowBytes());
207 SkASSERT_RELEASE(SkPngEncoder::Encode(&stream, bitmap.pixmap(), {}));
208 return SkImages::DeferredFromEncodedData(stream.detachAsData());
209}
static sk_sp< SkData > create_image_data(SkImageInfo *info)
#define SkASSERT_RELEASE(cond)
Definition SkAssert.h:100
SK_API sk_sp< SkImage > DeferredFromEncodedData(sk_sp< SkData > encoded, std::optional< SkAlphaType > alphaType=std::nullopt)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ create_data_image()

static sk_sp< SkImage > create_data_image ( )
static

Definition at line 157 of file ImageTest.cpp.

157 {
160 return SkImages::RasterFromData(info, std::move(data), info.minRowBytes());
161}
SK_API sk_sp< SkImage > RasterFromData(const SkImageInfo &info, sk_sp< SkData > pixels, size_t rowBytes)

◆ create_gpu_image()

static sk_sp< SkImage > create_gpu_image ( GrRecordingContext rContext,
bool  withMips = false,
skgpu::Budgeted  budgeted = skgpu::Budgeted::kYes 
)
static

Definition at line 210 of file ImageTest.cpp.

212 {
215 rContext, budgeted, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr, withMips);
216 draw_image_test_pattern(surface->getCanvas());
217 return surface->makeImageSnapshot();
218}
@ kBottomLeft_GrSurfaceOrigin
Definition GrTypes.h:149
static void draw_image_test_pattern(SkCanvas *canvas)
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
VkSurfaceKHR surface
Definition main.cc:48
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)

◆ create_image()

static sk_sp< SkImage > create_image ( )
static

Definition at line 139 of file ImageTest.cpp.

139 {
142 draw_image_test_pattern(surface->getCanvas());
143 return surface->makeImageSnapshot();
144}
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)

◆ create_image_data()

static sk_sp< SkData > create_image_data ( SkImageInfo info)
static

Definition at line 145 of file ImageTest.cpp.

145 {
147 const size_t rowBytes = info->minRowBytes();
148 sk_sp<SkData> data(SkData::MakeUninitialized(rowBytes * info->height()));
149 {
150 SkBitmap bm;
151 bm.installPixels(*info, data->writable_data(), rowBytes);
152 SkCanvas canvas(bm);
154 }
155 return data;
156}
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition SkBitmap.cpp:317
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition SkData.cpp:116

◆ create_image_large()

static sk_sp< SkImage > create_image_large ( int  maxTextureSize)
static

Definition at line 162 of file ImageTest.cpp.

162 {
163 const SkImageInfo info = SkImageInfo::MakeN32(maxTextureSize + 1, 32, kOpaque_SkAlphaType);
165 surface->getCanvas()->clear(SK_ColorWHITE);
168 surface->getCanvas()->drawRect(SkRect::MakeXYWH(4000, 2, 28000, 30), paint);
169 return surface->makeImageSnapshot();
170}
static SkPaint paint(SkColor color, float strokeWidth=-1.f, SkPaint::Join join=SkPaint::kMiter_Join)
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
void setColor(SkColor color)
Definition SkPaint.cpp:119
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659

◆ create_picture_image() [1/2]

static sk_sp< SkImage > create_picture_image ( )
static

Definition at line 171 of file ImageTest.cpp.

171 {
172 SkPictureRecorder recorder;
173 SkCanvas* canvas = recorder.beginRecording(10, 10);
174 canvas->clear(SK_ColorCYAN);
176 SkISize::Make(10, 10),
177 nullptr,
178 nullptr,
181}
constexpr SkColor SK_ColorCYAN
Definition SkColor.h:143
void clear(SkColor color)
Definition SkCanvas.h:1166
static sk_sp< SkColorSpace > MakeSRGB()
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
SK_API sk_sp< SkImage > DeferredFromPicture(sk_sp< SkPicture > picture, const SkISize &dimensions, const SkMatrix *matrix, const SkPaint *paint, BitDepth bitDepth, sk_sp< SkColorSpace > colorSpace, SkSurfaceProps props)
@ kU8
uses 8-bit unsigned int per color component
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:19

◆ create_picture_image() [2/2]

static sk_sp< SkImage > create_picture_image ( sk_sp< SkColorSpace space)
static

Definition at line 1299 of file ImageTest.cpp.

1299 {
1300 SkPictureRecorder recorder;
1301 SkCanvas* canvas = recorder.beginRecording(10, 10);
1302 canvas->clear(SK_ColorCYAN);
1304 SkISize::Make(10, 10),
1305 nullptr,
1306 nullptr,
1308 std::move(space));
1309}

◆ create_rasterproc_image()

static sk_sp< SkImage > create_rasterproc_image ( RasterDataHolder dataHolder)
static

Definition at line 193 of file ImageTest.cpp.

193 {
194 SkASSERT(dataHolder);
196 dataHolder->fData = create_image_data(&info);
197 return SkImages::RasterFromPixmap(SkPixmap(info, dataHolder->fData->data(), info.minRowBytes()),
199 dataHolder);
200}
#define SkASSERT(cond)
Definition SkAssert.h:116
const void * data() const
Definition SkData.h:37
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
sk_sp< SkData > fData
static void Release(const void *pixels, void *context)

◆ DEF_GANESH_TEST() [1/3]

DEF_GANESH_TEST ( AbandonedContextImage  ,
reporter  ,
options  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 667 of file ImageTest.cpp.

667 {
668 using Factory = sk_gpu_test::GrContextFactory;
669 for (int ct = 0; ct < skgpu::kContextTypeCount; ++ct) {
670 auto type = static_cast<Factory::ContextType>(ct);
671 std::unique_ptr<Factory> factory(new Factory);
672 if (!factory->get(type)) {
673 continue;
674 }
675
676 sk_sp<SkImage> img;
677 auto gsurf = SkSurfaces::RenderTarget(
678 factory->get(type),
681 1,
682 nullptr);
683 if (!gsurf) {
684 continue;
685 }
686 img = gsurf->makeImageSnapshot();
687 gsurf.reset();
688
689 auto rsurf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));
690
691 REPORTER_ASSERT(reporter, img->isValid(factory->get(type)));
692 REPORTER_ASSERT(reporter, img->isValid(rsurf->getCanvas()->recordingContext()));
693
694 factory->get(type)->abandonContext();
695 REPORTER_ASSERT(reporter, !img->isValid(factory->get(type)));
696 REPORTER_ASSERT(reporter, !img->isValid(rsurf->getCanvas()->recordingContext()));
697 // This shouldn't crash.
698 rsurf->getCanvas()->drawImage(img, 0, 0);
699
700 // Give up all other refs on the context.
701 factory.reset(nullptr);
702 REPORTER_ASSERT(reporter, !img->isValid(rsurf->getCanvas()->recordingContext()));
703 // This shouldn't crash.
704 rsurf->getCanvas()->drawImage(img, 0, 0);
705 }
706}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
void reset(T *ptr=nullptr)
Definition SkRefCnt.h:310
static const int kContextTypeCount
Definition ContextType.h:42
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)

◆ DEF_GANESH_TEST() [2/3]

DEF_GANESH_TEST ( SkImage_CrossContextGrayAlphaConfigs  ,
reporter  ,
options  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1171 of file ImageTest.cpp.

1174 {
1176 SkAutoPixmapStorage pixmap;
1177 pixmap.alloc(SkImageInfo::Make(4, 4, ct, kPremul_SkAlphaType));
1178
1179 for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
1180 GrContextFactory testFactory(options);
1181 skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
1182 ContextInfo ctxInfo = testFactory.getContextInfo(ctxType);
1183 auto dContext = ctxInfo.directContext();
1184 if (!dContext || !dContext->priv().caps()->crossContextTextureSupport()) {
1185 continue;
1186 }
1187
1190
1191 auto [view, viewCT] = skgpu::ganesh::AsView(dContext, image, skgpu::Mipmapped::kNo);
1194
1195 bool expectAlpha = kAlpha_8_SkColorType == ct;
1197 REPORTER_ASSERT(reporter, expectAlpha == GrColorTypeIsAlphaOnly(grCT));
1198 }
1199 }
1200}
const char * options
static constexpr SkColorType GrColorTypeToSkColorType(GrColorType ct)
static constexpr bool GrColorTypeIsAlphaOnly(GrColorType ct)
GrColorType
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
SkColorType
Definition SkColorType.h:19
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:34
SkColorType colorType() const
Definition SkImage.cpp:143
GrDirectContext * directContext() const
SK_API sk_sp< SkImage > CrossContextTextureFromPixmap(GrDirectContext *context, const SkPixmap &pixmap, bool buildMips, bool limitToMaxTextureSize=false)
std::tuple< GrSurfaceProxyView, GrColorType > AsView(GrRecordingContext *rContext, const SkImage *img, skgpu::Mipmapped mipmapped, GrImageTexGenPolicy policy)

◆ DEF_GANESH_TEST() [3/3]

DEF_GANESH_TEST ( SkImage_MakeCrossContextFromPixmapRelease  ,
reporter  ,
options  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1151 of file ImageTest.cpp.

1154 {
1156 SkPixmap pixmap;
1157 if (!ToolUtils::GetResourceAsBitmap("images/mandrill_128.png", &bitmap) ||
1158 !bitmap.peekPixels(&pixmap)) {
1159 ERRORF(reporter, "missing resource");
1160 return;
1161 }
1163 options,
1164 "SkImage_MakeCrossContextFromPixmapRelease",
1165 [&pixmap](GrDirectContext* dContext) {
1167 dContext, pixmap, false);
1168 });
1169}
static void test_cross_context_image(skiatest::Reporter *reporter, const GrContextOptions &options, const char *testName, const std::function< sk_sp< SkImage >(GrDirectContext *)> &imageMaker)
bool GetResourceAsBitmap(const char *resource, SkBitmap *dst)
Definition DecodeUtils.h:21

◆ DEF_GANESH_TEST_FOR_ALL_CONTEXTS()

DEF_GANESH_TEST_FOR_ALL_CONTEXTS ( ImageFlush  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1560 of file ImageTest.cpp.

1560 {
1561 auto dContext = ctxInfo.directContext();
1563 auto s = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kYes, ii, 1, nullptr);
1564
1565 s->getCanvas()->clear(SK_ColorRED);
1566 auto i0 = s->makeImageSnapshot();
1567 s->getCanvas()->clear(SK_ColorBLUE);
1568 auto i1 = s->makeImageSnapshot();
1569 s->getCanvas()->clear(SK_ColorGREEN);
1570 // Make a YUVA image.
1571 auto i2 = make_yuva_image(dContext);
1572
1573 // Flush all the setup work we did above and then make little lambda that reports the flush
1574 // count delta since the last time it was called.
1575 dContext->flushAndSubmit();
1576 auto numSubmits =
1577 [dContext,
1578 submitCnt = dContext->priv().getGpu()->stats()->numSubmitToGpus()]() mutable {
1579 int curr = dContext->priv().getGpu()->stats()->numSubmitToGpus();
1580 int n = curr - submitCnt;
1581 submitCnt = curr;
1582 return n;
1583 };
1584
1585 // Images aren't used therefore flush is ignored, but submit is still called.
1586 dContext->flushAndSubmit(i0);
1587 dContext->flushAndSubmit(i1);
1588 dContext->flushAndSubmit(i2);
1589 REPORTER_ASSERT(reporter, numSubmits() == 3);
1590
1591 // Syncing forces the flush to happen even if the images aren't used.
1592 dContext->flush(i0);
1593 dContext->submit(GrSyncCpu::kYes);
1594 REPORTER_ASSERT(reporter, numSubmits() == 1);
1595 dContext->flush(i1);
1596 dContext->submit(GrSyncCpu::kYes);
1597 REPORTER_ASSERT(reporter, numSubmits() == 1);
1598 dContext->flush(i2);
1599 dContext->submit(GrSyncCpu::kYes);
1600 REPORTER_ASSERT(reporter, numSubmits() == 1);
1601
1602 // Use image 1
1603 s->getCanvas()->drawImage(i1, 0, 0);
1604 // Flushing image 0 should do nothing, but submit is still called.
1605 dContext->flushAndSubmit(i0);
1606 REPORTER_ASSERT(reporter, numSubmits() == 1);
1607 // Flushing image 1 should flush.
1608 dContext->flushAndSubmit(i1);
1609 REPORTER_ASSERT(reporter, numSubmits() == 1);
1610 // Flushing image 2 should do nothing, but submit is still called.
1611 dContext->flushAndSubmit(i2);
1612 REPORTER_ASSERT(reporter, numSubmits() == 1);
1613
1614 // Use image 2
1615 s->getCanvas()->drawImage(i2, 0, 0);
1616 // Flushing image 0 should do nothing, but submit is still called.
1617 dContext->flushAndSubmit(i0);
1618 REPORTER_ASSERT(reporter, numSubmits() == 1);
1619 // Flushing image 1 do nothing, but submit is still called.
1620 dContext->flushAndSubmit(i1);
1621 REPORTER_ASSERT(reporter, numSubmits() == 1);
1622 // Flushing image 2 should flush.
1623 dContext->flushAndSubmit(i2);
1624 REPORTER_ASSERT(reporter, numSubmits() == 1);
1625 REPORTER_ASSERT(reporter, static_cast<SkImage_GaneshYUVA*>(as_IB(i2.get()))->isTextureBacked());
1626 s->getCanvas()->drawImage(i2, 0, 0);
1627 // Flushing image 0 should do nothing, but submit is still called.
1628 dContext->flushAndSubmit(i0);
1629 REPORTER_ASSERT(reporter, numSubmits() == 1);
1630 // Flushing image 1 do nothing, but submit is still called.
1631 dContext->flushAndSubmit(i1);
1632 REPORTER_ASSERT(reporter, numSubmits() == 1);
1633 // Flushing image 2 should flush.
1634 dContext->flushAndSubmit(i2);
1635 REPORTER_ASSERT(reporter, numSubmits() == 1);
1636}
static sk_sp< SkImage > make_yuva_image(GrDirectContext *dContext)
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
static SkImage_Base * as_IB(SkImage *image)
bool isTextureBacked() const override
struct MyStruct s

◆ DEF_GANESH_TEST_FOR_GL_CONTEXT() [1/2]

DEF_GANESH_TEST_FOR_GL_CONTEXT ( makeBackendTexture  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1202 of file ImageTest.cpp.

1202 {
1203 auto context = ctxInfo.directContext();
1204 sk_gpu_test::TestContext* testContext = ctxInfo.testContext();
1205 sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
1206
1207 GrContextFactory otherFactory;
1208 ContextInfo otherContextInfo = otherFactory.getContextInfo(ctxInfo.type());
1209
1210 testContext->makeCurrent();
1211 REPORTER_ASSERT(reporter, proxy);
1212 auto createLarge = [context] {
1213 return create_image_large(context->priv().caps()->maxTextureSize());
1214 };
1215 struct TestCase {
1216 std::function<sk_sp<SkImage>()> fImageFactory;
1217 bool fExpectation;
1218 bool fCanTakeDirectly;
1219 };
1220 TestCase testCases[] = {
1221 { create_image, true, false },
1222 { create_codec_image, true, false },
1223 { create_data_image, true, false },
1224 { create_picture_image, true, false },
1225 { [context] { return create_gpu_image(context); }, true, true },
1226 // Create a texture image in a another context.
1227 { [otherContextInfo] {
1228 auto restore = otherContextInfo.testContext()->makeCurrentAndAutoRestore();
1229 sk_sp<SkImage> otherContextImage = create_gpu_image(otherContextInfo.directContext());
1230 otherContextInfo.directContext()->flushAndSubmit();
1231 return otherContextImage;
1232 }, false, false },
1233 // Create an image that is too large to be texture backed.
1234 { createLarge, false, false }
1235 };
1236
1237 for (const TestCase& testCase : testCases) {
1238 sk_sp<SkImage> image(testCase.fImageFactory());
1239 if (!image) {
1240 ERRORF(reporter, "Failed to create image!");
1241 continue;
1242 }
1243
1244 GrBackendTexture origBackend;
1245 SkImages::GetBackendTextureFromImage(image, &origBackend, true);
1246 if (testCase.fCanTakeDirectly) {
1247 SkASSERT(origBackend.isValid());
1248 }
1249
1250 GrBackendTexture newBackend;
1253 context, std::move(image), &newBackend, &proc);
1254 if (result != testCase.fExpectation) {
1255 static const char *const kFS[] = { "fail", "succeed" };
1256 ERRORF(reporter, "This image was expected to %s but did not.",
1257 kFS[testCase.fExpectation]);
1258 }
1259
1260 if (result) {
1261 SkASSERT(newBackend.isValid());
1262 }
1263
1264 bool tookDirectly = result && GrBackendTexture::TestingOnly_Equals(origBackend, newBackend);
1265 if (testCase.fCanTakeDirectly != tookDirectly) {
1266 static const char *const kExpectedState[] = { "not expected", "expected" };
1267 ERRORF(reporter, "This backend texture was %s to be taken directly.",
1268 kExpectedState[testCase.fCanTakeDirectly]);
1269 }
1270
1271 context->flushAndSubmit();
1272 }
1273}
static sk_sp< SkImage > create_data_image()
static sk_sp< SkImage > create_codec_image()
static sk_sp< SkImage > create_gpu_image(GrRecordingContext *rContext, bool withMips=false, skgpu::Budgeted budgeted=skgpu::Budgeted::kYes)
static sk_sp< SkImage > create_picture_image()
static sk_sp< SkImage > create_image()
static sk_sp< SkImage > create_image_large(int maxTextureSize)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
TestContext * testContext() const
ContextInfo getContextInfo(ContextType type, ContextOverrides=ContextOverrides::kNone)
SkScopeExit makeCurrentAndAutoRestore() const
GAsyncResult * result
std::function< void(GrBackendTexture)> BackendTextureReleaseProc
SK_API bool GetBackendTextureFromImage(const SkImage *img, GrBackendTexture *outTexture, bool flushPendingGrContextIO, GrSurfaceOrigin *origin=nullptr)
SK_API bool MakeBackendTextureFromImage(GrDirectContext *context, sk_sp< SkImage > image, GrBackendTexture *backendTexture, BackendTextureReleaseProc *backendTextureReleaseProc)

◆ DEF_GANESH_TEST_FOR_GL_CONTEXT() [2/2]

DEF_GANESH_TEST_FOR_GL_CONTEXT ( SkImage_NewFromTextureRelease  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 933 of file ImageTest.cpp.

936 {
937 const int kWidth = 10;
938 const int kHeight = 10;
939
940 auto dContext = ctxInfo.directContext();
941
942 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext,
943 kWidth,
944 kHeight,
946 skgpu::Mipmapped::kNo,
947 GrRenderable::kNo,
948 GrProtected::kNo);
949 if (!mbet) {
950 ERRORF(reporter, "couldn't create backend texture\n");
951 return;
952 }
953
954 TextureReleaseChecker releaseChecker;
957 dContext,
958 mbet->texture(),
959 texOrigin,
962 /*color space*/ nullptr,
963 sk_gpu_test::ManagedBackendTexture::ReleaseProc,
964 mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker));
965
966 GrSurfaceOrigin readBackOrigin;
967 GrBackendTexture readBackBackendTex;
970 refImg, &readBackBackendTex, false, &readBackOrigin),
971 "Did not get backend texture");
972 if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, mbet->texture())) {
973 ERRORF(reporter, "backend mismatch\n");
974 }
976 GrBackendTexture::TestingOnly_Equals(readBackBackendTex, mbet->texture()));
977 if (readBackOrigin != texOrigin) {
978 ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
979 }
980 REPORTER_ASSERT(reporter, readBackOrigin == texOrigin);
981
982 // Now exercise the release proc
983 REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
984 refImg.reset(nullptr); // force a release of the image
985 REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
986}
GrSurfaceOrigin
Definition GrTypes.h:147
static const int kHeight
static const int kWidth
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
static void Release(void *self)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( GrContext_colorTypeSupportedAsImage  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 562 of file ImageTest.cpp.

565 {
566 using namespace skgpu;
567
568 auto dContext = ctxInfo.directContext();
569
570 Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
571
572 static constexpr int kSize = 10;
573
574 for (int ct = 0; ct < kLastEnum_SkColorType; ++ct) {
575 SkColorType colorType = static_cast<SkColorType>(ct);
576 bool can = dContext->colorTypeSupportedAsImage(colorType);
577
578 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(
579 dContext, kSize, kSize, colorType, skgpu::Mipmapped::kNo, GrRenderable::kNo,
580 isProtected);
581 sk_sp<SkImage> img;
582 if (mbet) {
583 img = SkImages::BorrowTextureFrom(dContext,
584 mbet->texture(),
586 colorType,
588 nullptr);
589 }
590 REPORTER_ASSERT(reporter, can == SkToBool(img),
591 "colorTypeSupportedAsImage:%d, actual:%d, ct:%d", can, SkToBool(img),
592 colorType);
593 }
594}
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
@ kLastEnum_SkColorType
last valid value
Definition SkColorType.h:55
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static constexpr int kSize
skgpu::Protected Protected
Protected
Definition GpuTypes.h:61

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImageBackendAccessAbandoned_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1275 of file ImageTest.cpp.

1278 {
1279 auto dContext = ctxInfo.directContext();
1280 sk_sp<SkImage> image(create_gpu_image(ctxInfo.directContext()));
1281 if (!image) {
1282 return;
1283 }
1284
1285 GrBackendTexture beTex;
1286 bool ok = SkImages::GetBackendTextureFromImage(image, &beTex, true);
1289
1290 dContext->abandonContext();
1291
1292 // After abandoning the context the backend texture should not be valid.
1295}
static bool ok(int result)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [3/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImageEncode_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 245 of file ImageTest.cpp.

248 {
249 auto dContext = ctxInfo.directContext();
250 test_encode(reporter, dContext, create_gpu_image(dContext).get());
251}
static void test_encode(skiatest::Reporter *reporter, GrDirectContext *dContext, SkImage *image)
const myers::Point & get(const myers::Segment &)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [4/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImageLegacyBitmap_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 873 of file ImageTest.cpp.

876 {
877 auto dContext = ctxInfo.directContext();
879 test_legacy_bitmap(reporter, dContext, image.get());
880}
static void test_legacy_bitmap(skiatest::Reporter *reporter, GrDirectContext *dContext, const SkImage *image)
T * get() const
Definition SkRefCnt.h:303

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [5/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImagePeek_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 917 of file ImageTest.cpp.

920 {
921 sk_sp<SkImage> image(create_gpu_image(ctxInfo.directContext()));
922 test_peek(reporter, image.get(), false);
923}
static void test_peek(skiatest::Reporter *reporter, SkImage *image, bool expectPeekSuccess)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [6/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImageReadPixels_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 811 of file ImageTest.cpp.

814 {
815 auto dContext = ctxInfo.directContext();
816 image_test_read_pixels(dContext, reporter, create_gpu_image(dContext).get());
817}
static void image_test_read_pixels(GrDirectContext *dContext, skiatest::Reporter *reporter, SkImage *image)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [7/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( ImageScalePixels_Gpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 1505 of file ImageTest.cpp.

1508 {
1509 const SkPMColor pmRed = SkPackARGB32(0xFF, 0xFF, 0, 0);
1510 const SkColor red = SK_ColorRED;
1511
1514 SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info);
1515 surface->getCanvas()->clear(red);
1516 sk_sp<SkImage> gpuImage = surface->makeImageSnapshot();
1517 test_scale_pixels(reporter, gpuImage.get(), pmRed);
1518}
static void test_scale_pixels(skiatest::Reporter *reporter, const SkImage *image, uint32_t expected)
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
uint32_t SkColor
Definition SkColor.h:37

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [8/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( SkImage_Ganesh2Cpu  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 402 of file ImageTest.cpp.

405 {
407 sk_sp<SkImage> image(create_gpu_image(ctxInfo.directContext()));
408 const auto desc = SkBitmapCacheDesc::Make(image.get());
409
411
412 // now we can test drawing a gpu-backed image into a cpu-backed surface
413
414 {
415 SkBitmap cachedBitmap;
416 REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &cachedBitmap));
417 }
418
419 surface->getCanvas()->drawImage(image, 0, 0);
420 {
421 SkBitmap cachedBitmap;
422 if (SkBitmapCache::Find(desc, &cachedBitmap)) {
423 REPORTER_ASSERT(reporter, cachedBitmap.isImmutable());
424 REPORTER_ASSERT(reporter, cachedBitmap.getPixels());
425 } else {
426 // unexpected, but not really a bug, since the cache is global and this test may be
427 // run w/ other threads competing for its budget.
428 SkDebugf("SkImage_Ganesh2Cpu : cachedBitmap was already purged\n");
429 }
430 }
431
432 image.reset(nullptr);
433 {
434 SkBitmap cachedBitmap;
435 REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &cachedBitmap));
436 }
437}
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool Find(const SkBitmapCacheDesc &, SkBitmap *result)
bool isImmutable() const
Definition SkBitmap.cpp:390
void * getPixels() const
Definition SkBitmap.h:273
static SkBitmapCacheDesc Make(const SkImage *)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [9/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( SkImage_makeNonTextureImage  ,
reporter  ,
contextInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 532 of file ImageTest.cpp.

535 {
536 auto dContext = contextInfo.directContext();
537
538 std::function<sk_sp<SkImage>()> imageFactories[] = {
543 [dContext] { return create_gpu_image(dContext); },
544 };
545 for (const auto& factory : imageFactories) {
546 sk_sp<SkImage> image = factory();
547 if (!image->isTextureBacked()) {
549 if (!(image = SkImages::TextureFromImage(dContext, image))) {
550 continue;
551 }
552 }
553 auto rasterImage = image->makeNonTextureImage();
554 if (!rasterImage) {
555 ERRORF(reporter, "makeNonTextureImage failed for texture-backed image.");
556 }
557 REPORTER_ASSERT(reporter, !rasterImage->isTextureBacked());
558 assert_equal(reporter, dContext, image.get(), nullptr, rasterImage.get());
559 }
560}
static void assert_equal(skiatest::Reporter *reporter, GrDirectContext *dContextA, SkImage *a, const SkIRect *subsetA, SkImage *b)
sk_sp< SkImage > makeNonTextureImage(GrDirectContext *=nullptr) const
Definition SkImage.cpp:251
virtual bool isTextureBacked() const =0
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [10/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( SkImage_makeTextureImage  ,
reporter  ,
contextInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 439 of file ImageTest.cpp.

442 {
443 auto dContext = contextInfo.directContext();
444 sk_gpu_test::TestContext* testContext = contextInfo.testContext();
445 GrContextFactory otherFactory;
446 ContextInfo otherContextInfo = otherFactory.getContextInfo(contextInfo.type());
447 testContext->makeCurrent();
448 std::function<sk_sp<SkImage>()> imageFactories[] = {
452 // Create an image from a picture.
454 // Create a texture image.
455 [dContext] { return create_gpu_image(dContext, true, skgpu::Budgeted::kYes); },
456 [dContext] { return create_gpu_image(dContext, false, skgpu::Budgeted::kNo); },
457 // Create a texture image in a another context.
458 [otherContextInfo] {
459 auto restore = otherContextInfo.testContext()->makeCurrentAndAutoRestore();
460 auto otherContextImage = create_gpu_image(otherContextInfo.directContext());
461 otherContextInfo.directContext()->flushAndSubmit();
462 return otherContextImage;
463 }};
464 for (auto mipmapped : {skgpu::Mipmapped::kNo, skgpu::Mipmapped::kYes}) {
465 for (const auto& factory : imageFactories) {
466 sk_sp<SkImage> image(factory());
467 if (!image) {
468 ERRORF(reporter, "Error creating image.");
469 continue;
470 }
471 GrTextureProxy* origProxy = nullptr;
472 bool origIsMippedTexture = false;
473
474 if ((origProxy = sk_gpu_test::GetTextureImageProxy(image.get(), dContext))) {
476 reporter,
477 (origProxy->mipmapped() == skgpu::Mipmapped::kYes) == image->hasMipmaps());
478 origIsMippedTexture = image->hasMipmaps();
479 }
480 for (auto budgeted : {skgpu::Budgeted::kNo, skgpu::Budgeted::kYes}) {
481 auto texImage = SkImages::TextureFromImage(dContext, image, mipmapped, budgeted);
482 if (!texImage) {
483 auto imageContext = as_IB(image)->context();
484 // We expect to fail if image comes from a different context
485 if (!image->isTextureBacked() || imageContext->priv().matches(dContext)) {
486 ERRORF(reporter, "makeTextureImage failed.");
487 }
488 continue;
489 }
490 if (!texImage->isTextureBacked()) {
491 ERRORF(reporter, "makeTextureImage returned non-texture image.");
492 continue;
493 }
494
495 GrTextureProxy* copyProxy = sk_gpu_test::GetTextureImageProxy(texImage.get(),
496 dContext);
497 SkASSERT(copyProxy);
498 // Did we ask for MIPs on a context that supports them?
499 bool validRequestForMips = (mipmapped == skgpu::Mipmapped::kYes &&
500 dContext->priv().caps()->mipmapSupport());
501 // Do we expect the "copy" to have MIPs?
502 bool shouldBeMipped = origIsMippedTexture || validRequestForMips;
503 REPORTER_ASSERT(reporter, shouldBeMipped == texImage->hasMipmaps());
505 reporter,
506 shouldBeMipped == (copyProxy->mipmapped() == skgpu::Mipmapped::kYes));
507
508 // We should only make a copy of an already texture-backed image if it didn't
509 // already have MIPs but we asked for MIPs and the context supports it.
510 if (image->isTextureBacked() && (!validRequestForMips || origIsMippedTexture)) {
511 if (origProxy->underlyingUniqueID() != copyProxy->underlyingUniqueID()) {
512 ERRORF(reporter, "makeTextureImage made unnecessary texture copy.");
513 }
514 } else {
515 GrTextureProxy* texProxy = sk_gpu_test::GetTextureImageProxy(texImage.get(),
516 dContext);
518 REPORTER_ASSERT(reporter, texProxy->isBudgeted() == budgeted);
519 }
520 if (image->width() != texImage->width() || image->height() != texImage->height()) {
521 ERRORF(reporter, "makeTextureImage changed the image size.");
522 }
523 if (image->alphaType() != texImage->alphaType()) {
524 ERRORF(reporter, "makeTextureImage changed image alpha type.");
525 }
526 }
527 }
528 }
529 dContext->flushAndSubmit();
530}
UniqueID underlyingUniqueID() const
skgpu::Budgeted isBudgeted() const
const skgpu::UniqueKey & getUniqueKey() const override
skgpu::Mipmapped mipmapped() const
virtual GrImageContext * context() const
bool hasMipmaps() const
Definition SkImage.cpp:283
bool isValid() const
Definition ResourceKey.h:51
GrTextureProxy * GetTextureImageProxy(SkImage *image, GrRecordingContext *rContext)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [11/11]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( UnpremulTextureImage  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 596 of file ImageTest.cpp.

599 {
600 SkBitmap bmp;
601 bmp.allocPixels(
603 for (int y = 0; y < 256; ++y) {
604 for (int x = 0; x < 256; ++x) {
605 *bmp.getAddr32(x, y) =
606 SkColorSetARGB((U8CPU)y, 255 - (U8CPU)y, (U8CPU)x, 255 - (U8CPU)x);
607 }
608 }
609 auto dContext = ctxInfo.directContext();
610 auto texImage = SkImages::TextureFromImage(dContext, bmp.asImage());
611 if (!texImage || texImage->alphaType() != kUnpremul_SkAlphaType) {
612 ERRORF(reporter, "Failed to make unpremul texture image.");
613 return;
614 }
615 SkBitmap unpremul;
617 kUnpremul_SkAlphaType, nullptr));
618 if (!texImage->readPixels(dContext, unpremul.info(), unpremul.getPixels(), unpremul.rowBytes(),
619 0, 0)) {
620 ERRORF(reporter, "Unpremul readback failed.");
621 return;
622 }
623 for (int y = 0; y < 256; ++y) {
624 for (int x = 0; x < 256; ++x) {
625 if (*bmp.getAddr32(x, y) != *unpremul.getAddr32(x, y)) {
626 ERRORF(reporter, "unpremul(0x%08x)->unpremul(0x%08x) at %d, %d.",
627 *bmp.getAddr32(x, y), *unpremul.getAddr32(x, y), x, y);
628 return;
629 }
630 }
631 }
635 if (!texImage->readPixels(dContext, premul.info(), premul.getPixels(), premul.rowBytes(),
636 0, 0)) {
637 ERRORF(reporter, "Unpremul readback failed.");
638 return;
639 }
640 for (int y = 0; y < 256; ++y) {
641 for (int x = 0; x < 256; ++x) {
642 uint32_t origColor = *bmp.getAddr32(x, y);
643 int32_t origA = (origColor >> 24) & 0xff;
644 float a = origA / 255.f;
645 int32_t origB = sk_float_round2int(((origColor >> 16) & 0xff) * a);
646 int32_t origG = sk_float_round2int(((origColor >> 8) & 0xff) * a);
647 int32_t origR = sk_float_round2int(((origColor >> 0) & 0xff) * a);
648
649 uint32_t read = *premul.getAddr32(x, y);
650 int32_t readA = (read >> 24) & 0xff;
651 int32_t readB = (read >> 16) & 0xff;
652 int32_t readG = (read >> 8) & 0xff;
653 int32_t readR = (read >> 0) & 0xff;
654 // We expect that alpha=1 and alpha=0 should come out exact. Otherwise allow a little
655 // bit of tolerance for GPU vs CPU premul math.
656 int32_t tol = (origA == 0 || origA == 255) ? 0 : 1;
657 if (origA != readA || SkTAbs(readB - origB) > tol || SkTAbs(readG - origG) > tol ||
658 SkTAbs(readR - origR) > tol) {
659 ERRORF(reporter, "unpremul(0x%08x)->premul(0x%08x) expected(0x%08x) at %d, %d.",
660 *bmp.getAddr32(x, y), *premul.getAddr32(x, y), origColor, x, y);
661 return;
662 }
663 }
664 }
665}
kUnpremul_SkAlphaType
unsigned U8CPU
Definition SkCPUTypes.h:18
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
#define sk_float_round2int(x)
static bool read(SkStream *stream, void *buffer, size_t amount)
static T SkTAbs(T value)
Definition SkTemplates.h:43
static uint32_t premul(uint32_t color)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition SkBitmap.cpp:252
sk_sp< SkImage > asImage() const
Definition SkBitmap.cpp:639
size_t rowBytes() const
Definition SkBitmap.h:238
const SkImageInfo & info() const
Definition SkBitmap.h:139
uint32_t * getAddr32(int x, int y) const
Definition SkBitmap.h:1250

◆ DEF_TEST() [1/19]

DEF_TEST ( Image_ColorSpace  ,
 
)

Definition at line 1311 of file ImageTest.cpp.

1311 {
1313 sk_sp<SkImage> image = ToolUtils::GetResourceAsImage("images/mandrill_512_q075.jpg");
1314 REPORTER_ASSERT(r, srgb.get() == image->colorSpace());
1315
1316 image = ToolUtils::GetResourceAsImage("images/webp-color-profile-lossy.webp");
1318 bool success = image->colorSpace()->isNumericalTransferFn(&fn);
1319 REPORTER_ASSERT(r, success);
1321
1326
1329 bitmap.allocPixels(info);
1330 image = bitmap.asImage();
1332
1335 image = surface->makeImageSnapshot();
1336 REPORTER_ASSERT(r, nullptr == image->colorSpace());
1337
1339 image = surface->makeImageSnapshot();
1341}
static sk_sp< SkColorSpace > rec2020()
static bool color_space_almost_equal(float a, float b)
bool isNumericalTransferFn(skcms_TransferFunction *fn) const
static bool Equals(const SkColorSpace *, const SkColorSpace *)
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
SkColorSpace * colorSpace() const
Definition SkImage.cpp:147
static constexpr skcms_Matrix3x3 kRec2020
static constexpr skcms_TransferFunction kSRGB

◆ DEF_TEST() [2/19]

DEF_TEST ( image_cubicresampler  ,
reporter   
)

Definition at line 1650 of file ImageTest.cpp.

1650 {
1651 auto diff = [reporter](const SkM44& a, const SkM44& b) {
1652 const float tolerance = 0.000001f;
1653 for (int r = 0; r < 4; ++r) {
1654 for (int c = 0; c < 4; ++c) {
1655 float d = std::abs(a.rc(r, c) - b.rc(r, c));
1656 REPORTER_ASSERT(reporter, d <= tolerance);
1657 }
1658 }
1659 };
1660
1662
1664}
constexpr SkM44 gCentripetalCatmulRom(0.0f/2, -1.0f/2, 2.0f/2, -1.0f/2, 2.0f/2, 0.0f/2, -5.0f/2, 3.0f/2, 0.0f/2, 1.0f/2, 4.0f/2, -3.0f/2, 0.0f/2, 0.0f/2, -1.0f/2, 1.0f/2)
constexpr SkM44 gMitchellNetravali(1.0f/18, -9.0f/18, 15.0f/18, -7.0f/18, 16.0f/18, 0.0f/18, -36.0f/18, 21.0f/18, 1.0f/18, 9.0f/18, 27.0f/18, -21.0f/18, 0.0f/18, 0.0f/18, -6.0f/18, 7.0f/18)
static SkM44 CubicResamplerMatrix(float B, float C)
Definition SkM44.h:150
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19

◆ DEF_TEST() [3/19]

DEF_TEST ( image_from_encoded_alphatype_override  ,
reporter   
)

Definition at line 1440 of file ImageTest.cpp.

1440 {
1441 sk_sp<SkData> data = GetResourceAsData("images/mandrill_32.png");
1442
1443 // Ensure that we can decode the image when we specifically request premul or unpremul, but
1444 // not when we request kOpaque
1448
1449 // Same tests as above, but using SkImageGenerators::MakeFromEncoded
1453}
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition Resources.cpp:42
std::unique_ptr< SkImageGenerator > MakeFromEncoded(sk_sp< SkData > data, std::optional< SkAlphaType > at)

◆ DEF_TEST() [4/19]

DEF_TEST ( Image_makeColorSpace  ,
 
)

Definition at line 1343 of file ImageTest.cpp.

1343 {
1346 fn.a = 1.f; fn.b = 0.f; fn.c = 0.f; fn.d = 0.f; fn.e = 0.f; fn.f = 0.f; fn.g = 1.8f;
1348
1349 SkBitmap srgbBitmap;
1351 *srgbBitmap.getAddr32(0, 0) = SkSwizzle_RGBA_to_PMColor(0xFF604020);
1352 srgbBitmap.setImmutable();
1353 sk_sp<SkImage> srgbImage = srgbBitmap.asImage();
1354 sk_sp<SkImage> p3Image = srgbImage->makeColorSpace(nullptr, p3);
1355 SkBitmap p3Bitmap;
1356 bool success = p3Image->asLegacyBitmap(&p3Bitmap);
1357
1358 auto almost_equal = [](int a, int b) { return SkTAbs(a - b) <= 2; };
1359
1360 REPORTER_ASSERT(r, success);
1361 REPORTER_ASSERT(r, almost_equal(0x28, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
1362 REPORTER_ASSERT(r, almost_equal(0x40, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
1363 REPORTER_ASSERT(r, almost_equal(0x5E, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
1364
1365 sk_sp<SkImage> adobeImage = srgbImage->makeColorSpace(nullptr, adobeGamut);
1366 SkBitmap adobeBitmap;
1367 success = adobeImage->asLegacyBitmap(&adobeBitmap);
1368 REPORTER_ASSERT(r, success);
1369 REPORTER_ASSERT(r, almost_equal(0x21, SkGetPackedR32(*adobeBitmap.getAddr32(0, 0))));
1370 REPORTER_ASSERT(r, almost_equal(0x31, SkGetPackedG32(*adobeBitmap.getAddr32(0, 0))));
1371 REPORTER_ASSERT(r, almost_equal(0x4C, SkGetPackedB32(*adobeBitmap.getAddr32(0, 0))));
1372
1373 srgbImage = ToolUtils::GetResourceAsImage("images/1x1.png");
1374 p3Image = srgbImage->makeColorSpace(nullptr, p3);
1375 success = p3Image->asLegacyBitmap(&p3Bitmap);
1376 REPORTER_ASSERT(r, success);
1377 REPORTER_ASSERT(r, almost_equal(0x8B, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
1378 REPORTER_ASSERT(r, almost_equal(0x82, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
1379 REPORTER_ASSERT(r, almost_equal(0x77, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
1380}
static bool almost_equal(float a, float b)
static SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c)
Definition SkColorData.h:83
#define SkGetPackedB32(packed)
Definition SkColorPriv.h:95
#define SkGetPackedR32(packed)
Definition SkColorPriv.h:93
#define SkGetPackedG32(packed)
Definition SkColorPriv.h:94
void setImmutable()
Definition SkBitmap.cpp:394
static constexpr skcms_Matrix3x3 kAdobeRGB
static constexpr skcms_Matrix3x3 kDisplayP3
static SkImageInfo MakeS32(int width, int height, SkAlphaType at)

◆ DEF_TEST() [5/19]

DEF_TEST ( Image_MakeFromRasterBitmap  ,
reporter   
)

Definition at line 253 of file ImageTest.cpp.

253 {
254 const struct {
255 SkCopyPixelsMode fCPM;
256 bool fExpectSameAsMutable;
257 bool fExpectSameAsImmutable;
258 } recs[] = {
259 { kIfMutable_SkCopyPixelsMode, false, true },
260 { kAlways_SkCopyPixelsMode, false, false },
261 { kNever_SkCopyPixelsMode, true, true },
262 };
263 for (auto rec : recs) {
264 SkPixmap pm;
265 SkBitmap bm;
266 bm.allocN32Pixels(100, 100);
267
268 auto img = SkMakeImageFromRasterBitmap(bm, rec.fCPM);
269 REPORTER_ASSERT(reporter, img->peekPixels(&pm));
270 const bool sameMutable = pm.addr32(0, 0) == bm.getAddr32(0, 0);
271 REPORTER_ASSERT(reporter, rec.fExpectSameAsMutable == sameMutable);
272 REPORTER_ASSERT(reporter, (bm.getGenerationID() == img->uniqueID()) == sameMutable);
273
274 bm.notifyPixelsChanged(); // force a new generation ID
275
276 bm.setImmutable();
277 img = SkMakeImageFromRasterBitmap(bm, rec.fCPM);
278 REPORTER_ASSERT(reporter, img->peekPixels(&pm));
279 const bool sameImmutable = pm.addr32(0, 0) == bm.getAddr32(0, 0);
280 REPORTER_ASSERT(reporter, rec.fExpectSameAsImmutable == sameImmutable);
281 REPORTER_ASSERT(reporter, (bm.getGenerationID() == img->uniqueID()) == sameImmutable);
282 }
283}
SK_SPI sk_sp< SkImage > SkMakeImageFromRasterBitmap(const SkBitmap &, SkCopyPixelsMode)
SkCopyPixelsMode
Definition SkImagePriv.h:17
@ kNever_SkCopyPixelsMode
never copy src pixels (even if they are marked mutable)
Definition SkImagePriv.h:20
@ kIfMutable_SkCopyPixelsMode
only copy src pixels if they are marked mutable
Definition SkImagePriv.h:18
@ kAlways_SkCopyPixelsMode
always copy src pixels (even if they are marked immutable)
Definition SkImagePriv.h:19
void notifyPixelsChanged() const
Definition SkBitmap.cpp:359
uint32_t getGenerationID() const
Definition SkBitmap.cpp:355
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition SkBitmap.cpp:226

◆ DEF_TEST() [6/19]

DEF_TEST ( image_newfrombitmap  ,
reporter   
)

Definition at line 363 of file ImageTest.cpp.

363 {
364 const struct {
365 void (*fMakeProc)(SkBitmap*);
366 bool fExpectPeekSuccess;
367 bool fExpectSharedID;
368 bool fExpectLazy;
369 } rec[] = {
370 { make_bitmap_mutable, true, false, false },
371 { make_bitmap_immutable, true, true, false },
372 };
373
374 for (size_t i = 0; i < std::size(rec); ++i) {
375 SkBitmap bm;
376 rec[i].fMakeProc(&bm);
377
379 SkPixmap pmap;
380
381 const bool sharedID = (image->uniqueID() == bm.getGenerationID());
382 REPORTER_ASSERT(reporter, sharedID == rec[i].fExpectSharedID);
383
384 const bool peekSuccess = image->peekPixels(&pmap);
385 REPORTER_ASSERT(reporter, peekSuccess == rec[i].fExpectPeekSuccess);
386
387 const bool lazy = image->isLazyGenerated();
388 REPORTER_ASSERT(reporter, lazy == rec[i].fExpectLazy);
389 }
390}
static void make_bitmap_mutable(SkBitmap *bm)
static void make_bitmap_immutable(SkBitmap *bm)
uint32_t uniqueID() const
Definition SkImage.h:309
virtual bool isLazyGenerated() const =0
bool peekPixels(SkPixmap *pixmap) const
Definition SkImage.cpp:34

◆ DEF_TEST() [7/19]

DEF_TEST ( Image_nonfinite_dst  ,
reporter   
)

Definition at line 1524 of file ImageTest.cpp.

1524 {
1526 auto img = any_image_will_do();
1527
1528 for (SkScalar bad : { SK_ScalarInfinity, SK_ScalarNaN}) {
1529 for (int bits = 1; bits <= 15; ++bits) {
1530 SkRect dst = { 0, 0, 10, 10 };
1531 if (bits & 1) dst.fLeft = bad;
1532 if (bits & 2) dst.fTop = bad;
1533 if (bits & 4) dst.fRight = bad;
1534 if (bits & 8) dst.fBottom = bad;
1535
1536 surf->getCanvas()->drawImageRect(img, dst, SkSamplingOptions());
1537
1538 // we should draw nothing
1539 ToolUtils::PixelIter iter(surf.get());
1540 while (void* addr = iter.next()) {
1541 REPORTER_ASSERT(reporter, *(SkPMColor*)addr == 0);
1542 }
1543 }
1544 }
1545}
static sk_sp< SkImage > any_image_will_do()
#define SK_ScalarNaN
Definition SkScalar.h:26
#define SK_ScalarInfinity
Definition SkScalar.h:24
float SkScalar
Definition extension.cpp:12
dst
Definition cp.py:12

◆ DEF_TEST() [8/19]

DEF_TEST ( Image_RetainSnapshot  ,
reporter   
)

Definition at line 320 of file ImageTest.cpp.

320 {
321 const SkPMColor red = SkPackARGB32(0xFF, 0xFF, 0, 0);
322 const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
325 surface->getCanvas()->clear(0xFF00FF00);
326
327 SkPMColor pixels[4];
328 memset(pixels, 0xFF, sizeof(pixels)); // init with values we don't expect
329 const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
330 const size_t dstRowBytes = 2 * sizeof(SkPMColor);
331
332 sk_sp<SkImage> image1(surface->makeImageSnapshot());
333 REPORTER_ASSERT(reporter, image1->readPixels(nullptr, dstInfo, pixels, dstRowBytes, 0, 0));
334 for (size_t i = 0; i < std::size(pixels); ++i) {
335 REPORTER_ASSERT(reporter, pixels[i] == green);
336 }
337
341
342 surface->getCanvas()->drawRect(SkRect::MakeXYWH(1, 1, 1, 1), paint);
343
344 sk_sp<SkImage> image2(surface->makeImageSnapshot());
345 REPORTER_ASSERT(reporter, image2->readPixels(nullptr, dstInfo, pixels, dstRowBytes, 0, 0));
346 REPORTER_ASSERT(reporter, pixels[0] == green);
347 REPORTER_ASSERT(reporter, pixels[1] == green);
348 REPORTER_ASSERT(reporter, pixels[2] == green);
349 REPORTER_ASSERT(reporter, pixels[3] == red);
350}
void setBlendMode(SkBlendMode mode)
Definition SkPaint.cpp:151

◆ DEF_TEST() [9/19]

DEF_TEST ( image_roundtrip_encode  ,
reporter   
)

Definition at line 1410 of file ImageTest.cpp.

1410 {
1411 SkBitmap bm0;
1412 make_all_premul(&bm0);
1413
1414 auto img0 = bm0.asImage();
1415 sk_sp<SkData> data = SkPngEncoder::Encode(nullptr, img0.get(), {});
1416 auto img1 = SkImages::DeferredFromEncodedData(data);
1417
1418 SkBitmap bm1;
1420 img1->readPixels(nullptr, bm1.info(), bm1.getPixels(), bm1.rowBytes(), 0, 0);
1421
1422 REPORTER_ASSERT(reporter, equal(bm0, bm1));
1423}
static bool equal(const SkBitmap &a, const SkBitmap &b)
static void make_all_premul(SkBitmap *bm)

◆ DEF_TEST() [10/19]

DEF_TEST ( image_roundtrip_premul  ,
reporter   
)

Definition at line 1425 of file ImageTest.cpp.

1425 {
1426 SkBitmap bm0;
1427 make_all_premul(&bm0);
1428
1429 SkBitmap bm1;
1431 bm0.readPixels(bm1.info(), bm1.getPixels(), bm1.rowBytes(), 0, 0);
1432
1433 SkBitmap bm2;
1435 bm1.readPixels(bm2.info(), bm2.getPixels(), bm2.rowBytes(), 0, 0);
1436
1437 REPORTER_ASSERT(reporter, equal(bm0, bm2));
1438}
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY) const
Definition SkBitmap.cpp:482

◆ DEF_TEST() [11/19]

DEF_TEST ( Image_Serialize_Encoding_Failure  ,
reporter   
)

Definition at line 286 of file ImageTest.cpp.

286 {
288 surface->getCanvas()->clear(SK_ColorGREEN);
289 sk_sp<SkImage> image(surface->makeImageSnapshot());
291
292 SkPictureRecorder recorder;
293 SkCanvas* canvas = recorder.beginRecording(100, 100);
294 canvas->drawImage(image.get(), 0, 0, SkSamplingOptions());
296 REPORTER_ASSERT(reporter, picture);
298
299 bool was_called = false;
300 SkSerialProcs procs;
301 procs.fImageProc = [](SkImage*, void* called) {
302 *(bool*)called = true;
303 return SkData::MakeEmpty();
304 };
305 procs.fImageCtx = &was_called;
306
307 REPORTER_ASSERT(reporter, !was_called);
308 auto data = picture->serialize(&procs);
309 REPORTER_ASSERT(reporter, was_called);
310 REPORTER_ASSERT(reporter, data && data->size() > 0);
311
312 auto deserialized = SkPicture::MakeFromData(data->data(), data->size());
313 REPORTER_ASSERT(reporter, deserialized);
314 REPORTER_ASSERT(reporter, deserialized->approximateOpCount() > 0);
315}
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1474
static sk_sp< SkData > MakeEmpty()
Definition SkData.cpp:94
sk_sp< SkData > serialize(const SkSerialProcs *procs=nullptr) const
static sk_sp< SkPicture > MakeFromData(const SkData *data, const SkDeserialProcs *procs=nullptr)
virtual int approximateOpCount(bool nested=false) const =0
sk_sp< const SkPicture > picture
Definition SkRecords.h:299
SkSerialImageProc fImageProc

◆ DEF_TEST() [12/19]

DEF_TEST ( image_subset_encode_skbug_7752  ,
reporter   
)

Definition at line 1666 of file ImageTest.cpp.

1666 {
1667 sk_sp<SkImage> image = ToolUtils::GetResourceAsImage("images/mandrill_128.png");
1668 const int W = image->width();
1669 const int H = image->height();
1670
1671 auto check_roundtrip = [&](const sk_sp<SkImage>& img) {
1672 auto img2 = SkImages::DeferredFromEncodedData(SkPngEncoder::Encode(nullptr, img.get(), {}));
1673 REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img.get(), img2.get()));
1674 };
1675 check_roundtrip(image); // should trivially pass
1676 check_roundtrip(image->makeSubset(nullptr, {0, 0, W/2, H/2}));
1677 check_roundtrip(image->makeSubset(nullptr, {W/2, H/2, W, H}));
1678 check_roundtrip(image->makeColorSpace(nullptr, SkColorSpace::MakeSRGBLinear()));
1679}
#define W
Definition aaa.cpp:17
static sk_sp< SkColorSpace > MakeSRGBLinear()
virtual sk_sp< SkImage > makeColorSpace(GrDirectContext *direct, sk_sp< SkColorSpace > target) const =0
virtual sk_sp< SkImage > makeSubset(GrDirectContext *direct, const SkIRect &subset) const =0
bool equal_pixels(const SkPixmap &a, const SkPixmap &b)
Definition SkMD5.cpp:129

◆ DEF_TEST() [13/19]

DEF_TEST ( ImageDataRef  ,
reporter   
)

Definition at line 723 of file ImageTest.cpp.

723 {
725 size_t rowBytes = info.minRowBytes();
726 size_t size = info.computeByteSize(rowBytes);
728 REPORTER_ASSERT(reporter, data->unique());
730 REPORTER_ASSERT(reporter, !data->unique());
731 image.reset();
732 REPORTER_ASSERT(reporter, data->unique());
733}
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259

◆ DEF_TEST() [14/19]

DEF_TEST ( ImageEmpty  ,
reporter   
)

Definition at line 713 of file ImageTest.cpp.

713 {
714 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
715 SkPixmap pmap(info, nullptr, 0);
717 REPORTER_ASSERT(reporter, nullptr == SkImages::RasterFromData(info, nullptr, 0));
718 REPORTER_ASSERT(reporter, nullptr == SkImages::RasterFromPixmap(pmap, nullptr, nullptr));
720 nullptr == SkImages::DeferredFromGenerator(std::make_unique<EmptyGenerator>()));
721}
SK_API sk_sp< SkImage > DeferredFromGenerator(std::unique_ptr< SkImageGenerator > imageGenerator)
SK_API sk_sp< SkImage > RasterFromPixmapCopy(const SkPixmap &pixmap)

◆ DEF_TEST() [15/19]

DEF_TEST ( ImageEncode  ,
reporter   
)

Definition at line 241 of file ImageTest.cpp.

241 {
242 test_encode(reporter, nullptr, create_image().get());
243}

◆ DEF_TEST() [16/19]

DEF_TEST ( ImageLegacyBitmap  ,
reporter   
)

Definition at line 857 of file ImageTest.cpp.

857 {
860
863
864 RasterDataHolder dataHolder;
865 image = create_rasterproc_image(&dataHolder);
867 image.reset();
868 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
869
872}
static sk_sp< SkImage > create_rasterproc_image(RasterDataHolder *dataHolder)

◆ DEF_TEST() [17/19]

DEF_TEST ( ImagePeek  ,
reporter   
)

Definition at line 901 of file ImageTest.cpp.

901 {
903 test_peek(reporter, image.get(), true);
904
906 test_peek(reporter, image.get(), true);
907
908 RasterDataHolder dataHolder;
909 image = create_rasterproc_image(&dataHolder);
910 test_peek(reporter, image.get(), true);
911 image.reset();
912 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
913
915 test_peek(reporter, image.get(), false);
916}

◆ DEF_TEST() [18/19]

DEF_TEST ( ImageReadPixels  ,
reporter   
)

Definition at line 795 of file ImageTest.cpp.

795 {
798
801
802 RasterDataHolder dataHolder;
803 image = create_rasterproc_image(&dataHolder);
805 image.reset();
806 REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
807
810}

◆ DEF_TEST() [19/19]

DEF_TEST ( ImageScalePixels  ,
reporter   
)

Definition at line 1488 of file ImageTest.cpp.

1488 {
1489 const SkPMColor pmRed = SkPackARGB32(0xFF, 0xFF, 0, 0);
1490 const SkColor red = SK_ColorRED;
1491
1492 // Test raster image
1495 surface->getCanvas()->clear(red);
1496 sk_sp<SkImage> rasterImage = surface->makeImageSnapshot();
1497 test_scale_pixels(reporter, rasterImage.get(), pmRed);
1498
1499 // Test encoded image
1500 sk_sp<SkData> data = SkPngEncoder::Encode(nullptr, rasterImage.get(), {});
1502 test_scale_pixels(reporter, codecImage.get(), pmRed);
1503}

◆ draw_image_test_pattern()

static void draw_image_test_pattern ( SkCanvas canvas)
static

Definition at line 133 of file ImageTest.cpp.

133 {
134 canvas->clear(SK_ColorWHITE);
137 canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
138}
void drawRect(const SkRect &rect, const SkPaint &paint)

◆ equal()

static bool equal ( const SkBitmap a,
const SkBitmap b 
)
static

Definition at line 1395 of file ImageTest.cpp.

1395 {
1396 SkASSERT(a.width() == b.width());
1397 SkASSERT(a.height() == b.height());
1398 for (int y = 0; y < a.height(); ++y) {
1399 for (int x = 0; x < a.width(); ++x) {
1400 SkPMColor pa = *a.getAddr32(x, y);
1401 SkPMColor pb = *b.getAddr32(x, y);
1402 if (pa != pb) {
1403 return false;
1404 }
1405 }
1406 }
1407 return true;
1408}

◆ gCentripetalCatmulRom()

constexpr SkM44 gCentripetalCatmulRom ( 0.0f/  2,
-1.0f/  2,
2.0f/  2,
-1.0f/  2,
2.0f/  2,
0.0f/  2,
-5.0f/  2,
3.0f/  2,
0.0f/  2,
1.0f/  2,
4.0f/  2,
-3.0f/  2,
0.0f/  2,
0.0f/  2,
-1.0f/  2,
1.0f/  2 
)
constexpr

◆ gMitchellNetravali()

constexpr SkM44 gMitchellNetravali ( 1.0f/  18,
-9.0f/  18,
15.0f/  18,
-7.0f/  18,
16.0f/  18,
0.0f/  18,
-36.0f/  18,
21.0f/  18,
1.0f/  18,
9.0f/  18,
27.0f/  18,
-21.0f/  18,
0.0f/  18,
0.0f/  18,
-6.0f/  18,
7.0f/  18 
)
constexpr

◆ has_pixels()

static bool has_pixels ( const SkPMColor  pixels[],
int  count,
SkPMColor  expected 
)
static

Definition at line 735 of file ImageTest.cpp.

735 {
736 for (int i = 0; i < count; ++i) {
737 if (pixels[i] != expected) {
738 return false;
739 }
740 }
741 return true;
742}
int count

◆ image_test_read_pixels()

static void image_test_read_pixels ( GrDirectContext dContext,
skiatest::Reporter reporter,
SkImage image 
)
static

Definition at line 744 of file ImageTest.cpp.

745 {
746 if (!image) {
747 ERRORF(reporter, "Failed to create image!");
748 return;
749 }
751 const SkPMColor notExpected = ~expected;
752
753 const int w = 2, h = 2;
754 const size_t rowBytes = w * sizeof(SkPMColor);
755 SkPMColor pixels[w*h];
756
758
760 REPORTER_ASSERT(reporter, !image->readPixels(dContext, info, pixels, rowBytes, 0, 0));
761
762 // out-of-bounds should fail
764 REPORTER_ASSERT(reporter, !image->readPixels(dContext, info, pixels, rowBytes, -w, 0));
765 REPORTER_ASSERT(reporter, !image->readPixels(dContext, info, pixels, rowBytes, 0, -h));
766 REPORTER_ASSERT(reporter, !image->readPixels(dContext, info, pixels, rowBytes,
767 image->width(), 0));
768 REPORTER_ASSERT(reporter, !image->readPixels(dContext, info, pixels, rowBytes,
769 0, image->height()));
770
771 // top-left should succeed
772 SkOpts::memset32(pixels, notExpected, w*h);
773 REPORTER_ASSERT(reporter, image->readPixels(dContext, info, pixels, rowBytes, 0, 0));
774 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
775
776 // bottom-right should succeed
777 SkOpts::memset32(pixels, notExpected, w*h);
778 REPORTER_ASSERT(reporter, image->readPixels(dContext, info, pixels, rowBytes,
779 image->width() - w, image->height() - h));
780 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
781
782 // partial top-left should succeed
783 SkOpts::memset32(pixels, notExpected, w*h);
784 REPORTER_ASSERT(reporter, image->readPixels(dContext, info, pixels, rowBytes, -1, -1));
785 REPORTER_ASSERT(reporter, pixels[3] == expected);
786 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
787
788 // partial bottom-right should succeed
789 SkOpts::memset32(pixels, notExpected, w*h);
790 REPORTER_ASSERT(reporter, image->readPixels(dContext, info, pixels, rowBytes,
791 image->width() - 1, image->height() - 1));
792 REPORTER_ASSERT(reporter, pixels[0] == expected);
793 REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
794}
static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected)
SK_API SkPMColor SkPreMultiplyColor(SkColor c)
Definition SkColor.cpp:21
void(* memset32)(uint32_t[], uint32_t, int)
SkScalar w
SkScalar h
static SkImageInfo MakeUnknown()

◆ make_all_premul()

static void make_all_premul ( SkBitmap bm)
static

Definition at line 1384 of file ImageTest.cpp.

1384 {
1386 for (int a = 0; a < 256; ++a) {
1387 for (int r = 0; r < 256; ++r) {
1388 // make all valid premul combinations
1389 int c = std::min(a, r);
1390 *bm->getAddr32(a, r) = SkPackARGB32(a, c, c, c);
1391 }
1392 }
1393}

◆ make_bitmap_immutable()

static void make_bitmap_immutable ( SkBitmap bm)
static

Definition at line 358 of file ImageTest.cpp.

358 {
359 bm->allocN32Pixels(10, 10);
360 bm->setImmutable();
361}

◆ make_bitmap_mutable()

static void make_bitmap_mutable ( SkBitmap bm)
static

Definition at line 354 of file ImageTest.cpp.

354 {
355 bm->allocN32Pixels(10, 10);
356}

◆ make_yuva_image()

static sk_sp< SkImage > make_yuva_image ( GrDirectContext dContext)
static

Definition at line 1547 of file ImageTest.cpp.

1547 {
1550 SkYUVAInfo yuvaInfo({1, 1},
1554 const SkPixmap pmaps[] = {pm, pm, pm};
1555 auto yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, pmaps);
1556
1557 return SkImages::TextureFromYUVAPixmaps(dContext, yuvaPixmaps);
1558}
@ kJPEG_Full_SkYUVColorSpace
describes full range
Definition SkImageInfo.h:69
@ kY_U_V
Plane 0: Y, Plane 1: U, Plane 2: V.
@ k444
No subsampling. UV values for each Y.
static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo &, const SkPixmap[kMaxPlanes])
SK_API sk_sp< SkImage > TextureFromYUVAPixmaps(GrRecordingContext *context, const SkYUVAPixmaps &pixmaps, skgpu::Mipmapped buildMips, bool limitToMaxTextureSize, sk_sp< SkColorSpace > imageColorSpace)

◆ read_pixels_info()

SkImageInfo read_pixels_info ( SkImage image)

Definition at line 98 of file ImageTest.cpp.

98 {
99 if (image->colorSpace()) {
101 }
102
104}

◆ test_cross_context_image()

static void test_cross_context_image ( skiatest::Reporter reporter,
const GrContextOptions options,
const char *  testName,
const std::function< sk_sp< SkImage >(GrDirectContext *)> &  imageMaker 
)
static

Definition at line 988 of file ImageTest.cpp.

992 {
993 for (int i = 0; i < skgpu::kContextTypeCount; ++i) {
994 GrContextFactory testFactory(options);
995 skgpu::ContextType ctxType = static_cast<skgpu::ContextType>(i);
996 ContextInfo ctxInfo = testFactory.getContextInfo(ctxType);
997 auto dContext = ctxInfo.directContext();
998 if (!dContext) {
999 continue;
1000 }
1001
1002 // If we don't have proper support for this feature, the factory will fallback to returning
1003 // codec-backed images. Those will "work", but some of our checks will fail because we
1004 // expect the cross-context images not to work on multiple contexts at once.
1005 if (!dContext->priv().caps()->crossContextTextureSupport()) {
1006 continue;
1007 }
1008
1009 // We test three lifetime patterns for a single context:
1010 // 1) Create image, free image
1011 // 2) Create image, draw, flush, free image
1012 // 3) Create image, draw, free image, flush
1013 // ... and then repeat the last two patterns with drawing on a second* context:
1014 // 4) Create image, draw*, flush*, free image
1015 // 5) Create image, draw*, free image, flush*
1016
1017 // Case #1: Create image, free image
1018 {
1019 sk_sp<SkImage> refImg(imageMaker(dContext));
1020 refImg.reset(nullptr); // force a release of the image
1021 }
1022
1025 if (!surface) {
1026 ERRORF(reporter, "SkSurfaces::RenderTarget failed for %s.", testName);
1027 continue;
1028 }
1029
1030 SkCanvas* canvas = surface->getCanvas();
1031
1032 // Case #2: Create image, draw, flush, free image
1033 {
1034 sk_sp<SkImage> refImg(imageMaker(dContext));
1035
1036 canvas->drawImage(refImg, 0, 0);
1037 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
1038
1039 refImg.reset(nullptr); // force a release of the image
1040 }
1041
1042 // Case #3: Create image, draw, free image, flush
1043 {
1044 sk_sp<SkImage> refImg(imageMaker(dContext));
1045
1046 canvas->drawImage(refImg, 0, 0);
1047 refImg.reset(nullptr); // force a release of the image
1048
1049 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
1050 }
1051
1052 // Configure second context
1053 sk_gpu_test::TestContext* testContext = ctxInfo.testContext();
1054
1055 ContextInfo otherContextInfo = testFactory.getSharedContextInfo(dContext);
1056 auto otherCtx = otherContextInfo.directContext();
1057 sk_gpu_test::TestContext* otherTestContext = otherContextInfo.testContext();
1058
1059 // Creating a context in a share group may fail
1060 if (!otherCtx) {
1061 continue;
1062 }
1063
1065 canvas = surface->getCanvas();
1066
1067 // Case #4: Create image, draw*, flush*, free image
1068 {
1069 testContext->makeCurrent();
1070 sk_sp<SkImage> refImg(imageMaker(dContext));
1071
1072 otherTestContext->makeCurrent();
1073 canvas->drawImage(refImg, 0, 0);
1074 otherCtx->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
1075
1076 testContext->makeCurrent();
1077 refImg.reset(nullptr); // force a release of the image
1078 }
1079
1080 // Case #5: Create image, draw*, free image, flush*
1081 {
1082 testContext->makeCurrent();
1083 sk_sp<SkImage> refImg(imageMaker(dContext));
1084
1085 otherTestContext->makeCurrent();
1086 canvas->drawImage(refImg, 0, 0);
1087
1088 testContext->makeCurrent();
1089 refImg.reset(nullptr); // force a release of the image
1090
1091 otherTestContext->makeCurrent();
1092 // Sync is specifically here for vulkan to guarantee the command buffer will finish
1093 // which is when we call the ReleaseProc.
1094 otherCtx->flushAndSubmit(surface.get(), GrSyncCpu::kYes);
1095 }
1096
1097 // Case #6: Verify that only one context can be using the image at a time
1098 {
1099 // Suppress warnings about trying to use a texture in two contexts.
1100 GrRecordingContextPriv::AutoSuppressWarningMessages aswm(otherCtx);
1101
1102 testContext->makeCurrent();
1103 sk_sp <SkImage> refImg(imageMaker(dContext));
1104 GrSurfaceProxyView view, otherView, viewSecondRef;
1105
1106 // Any context should be able to borrow the texture at this point
1107
1108 std::tie(view, std::ignore) =
1109 skgpu::ganesh::AsView(dContext, refImg, skgpu::Mipmapped::kNo);
1111
1112 // But once it's borrowed, no other context should be able to borrow
1113 otherTestContext->makeCurrent();
1114 std::tie(otherView, std::ignore) =
1115 skgpu::ganesh::AsView(otherCtx, refImg, skgpu::Mipmapped::kNo);
1116 REPORTER_ASSERT(reporter, !otherView);
1117
1118 // Original context (that's already borrowing) should be okay
1119 testContext->makeCurrent();
1120 std::tie(viewSecondRef, std::ignore) =
1121 skgpu::ganesh::AsView(dContext, refImg, skgpu::Mipmapped::kNo);
1122 REPORTER_ASSERT(reporter, viewSecondRef);
1123
1124 // Release first ref from the original context
1125 view.reset();
1126
1127 // We released one proxy but not the other from the current borrowing context. Make sure
1128 // a new context is still not able to borrow the texture.
1129 otherTestContext->makeCurrent();
1130 std::tie(otherView, std::ignore) =
1131 skgpu::ganesh::AsView(otherCtx, refImg, skgpu::Mipmapped::kNo);
1132 REPORTER_ASSERT(reporter, !otherView);
1133
1134 // Release second ref from the original context
1135 testContext->makeCurrent();
1136 viewSecondRef.reset();
1137
1138 // Now we should be able to borrow the texture from the other context
1139 otherTestContext->makeCurrent();
1140 std::tie(otherView, std::ignore) =
1141 skgpu::ganesh::AsView(otherCtx, refImg, skgpu::Mipmapped::kNo);
1142 REPORTER_ASSERT(reporter, otherView);
1143
1144 // Release everything
1145 otherView.reset();
1146 refImg.reset(nullptr);
1147 }
1148 }
1149}

◆ test_encode()

static void test_encode ( skiatest::Reporter reporter,
GrDirectContext dContext,
SkImage image 
)
static

Definition at line 220 of file ImageTest.cpp.

220 {
221 const SkIRect ir = SkIRect::MakeXYWH(5, 5, 10, 10);
222 sk_sp<SkData> origEncoded = SkPngEncoder::Encode(dContext, image, {});
223 REPORTER_ASSERT(reporter, origEncoded);
224 REPORTER_ASSERT(reporter, origEncoded->size() > 0);
225
227 if (!decoded) {
228 ERRORF(reporter, "failed to decode image!");
229 return;
230 }
231 REPORTER_ASSERT(reporter, decoded);
232 assert_equal(reporter, dContext, image, nullptr, decoded.get());
233
234 // Now see if we can instantiate an image from a subset of the surface/origEncoded
235
236 decoded = SkImages::DeferredFromEncodedData(origEncoded)->makeSubset(nullptr, ir);
237 REPORTER_ASSERT(reporter, decoded);
238 assert_equal(reporter, dContext, image, &ir, decoded.get());
239}
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition SkRect.h:104

◆ test_legacy_bitmap()

static void test_legacy_bitmap ( skiatest::Reporter reporter,
GrDirectContext dContext,
const SkImage image 
)
static

Definition at line 836 of file ImageTest.cpp.

837 {
838 if (!image) {
839 ERRORF(reporter, "Failed to create image.");
840 return;
841 }
845
846 // Test subsetting to exercise the rowBytes logic.
847 SkBitmap tmp;
848 REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(image->width() / 2,
849 image->height() / 2)));
850 sk_sp<SkImage> subsetImage(tmp.asImage());
851 REPORTER_ASSERT(reporter, subsetImage.get());
852
853 SkBitmap subsetBitmap;
854 REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap));
855 check_legacy_bitmap(reporter, nullptr, subsetImage.get(), subsetBitmap);
856}
static void check_legacy_bitmap(skiatest::Reporter *reporter, GrDirectContext *dContext, const SkImage *image, const SkBitmap &bitmap)
bool asLegacyBitmap(SkBitmap *bitmap, LegacyBitmapMode legacyBitmapMode=kRO_LegacyBitmapMode) const
Definition SkImage.cpp:224
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56

◆ test_peek()

static void test_peek ( skiatest::Reporter reporter,
SkImage image,
bool  expectPeekSuccess 
)
static

Definition at line 882 of file ImageTest.cpp.

882 {
883 if (!image) {
884 ERRORF(reporter, "Failed to create image!");
885 return;
886 }
887 SkPixmap pm;
888 bool success = image->peekPixels(&pm);
889 REPORTER_ASSERT(reporter, expectPeekSuccess == success);
890 if (success) {
891 const SkImageInfo& info = pm.info();
892 REPORTER_ASSERT(reporter, 20 == info.width());
893 REPORTER_ASSERT(reporter, 20 == info.height());
894 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
896 kOpaque_SkAlphaType == info.alphaType());
897 REPORTER_ASSERT(reporter, info.minRowBytes() <= pm.rowBytes());
899 }
900}
size_t rowBytes() const
Definition SkPixmap.h:145
const SkImageInfo & info() const
Definition SkPixmap.h:135

◆ test_scale_pixels()

static void test_scale_pixels ( skiatest::Reporter reporter,
const SkImage image,
uint32_t  expected 
)
static

Definition at line 1471 of file ImageTest.cpp.

1472 {
1474
1475 // Make sure to test kDisallow first, so we don't just get a cache hit in that case
1477 SkAutoPixmapStorage scaled;
1478 scaled.alloc(info);
1480 ERRORF(reporter, "Failed to scale image");
1481 continue;
1482 }
1483
1484 check_scaled_pixels(reporter, &scaled, expected);
1485 }
1486}
static void check_scaled_pixels(skiatest::Reporter *reporter, SkPixmap *pmap, uint32_t expected)
@ kDisallow_CachingHint
disallows internally caching decoded and copied pixels
Definition SkImage.h:463
@ kAllow_CachingHint
allows internally caching decoded and copied pixels
Definition SkImage.h:462
bool scalePixels(const SkPixmap &dst, const SkSamplingOptions &, CachingHint cachingHint=kAllow_CachingHint) const
Definition SkImage.cpp:118