1 /*
2  * Copyright 2016 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 
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkImage.h"
10 #include "include/core/SkImageInfo.h"
11 #include "include/core/SkRect.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkSurfaceProps.h"
14 #include "include/core/SkTypes.h"
15 #include "include/gpu/GpuTypes.h"
16 #include "include/gpu/GrDirectContext.h"
17 #include "include/gpu/GrTypes.h"
18 #include "src/core/SkDevice.h"
19 #include "src/core/SkSpecialImage.h"
20 #include "src/gpu/SkBackingFit.h"
21 #include "src/gpu/ganesh/Device_v1.h"
22 #include "src/gpu/ganesh/GrDirectContextPriv.h"
23 #include "tests/CtsEnforcement.h"
24 #include "tests/Test.h"
25 
26 struct GrContextOptions;
27 
28 class DeviceTestingAccess {
29 public:
MakeSpecial(SkBaseDevice * dev,const SkBitmap & bm)30     static sk_sp<SkSpecialImage> MakeSpecial(SkBaseDevice* dev, const SkBitmap& bm) {
31         return dev->makeSpecial(bm);
32     }
33 
MakeSpecial(SkBaseDevice * dev,SkImage * img)34     static sk_sp<SkSpecialImage> MakeSpecial(SkBaseDevice* dev, SkImage* img) {
35         return dev->makeSpecial(img);
36     }
37 
SnapSpecial(SkBaseDevice * dev)38     static sk_sp<SkSpecialImage> SnapSpecial(SkBaseDevice* dev) {
39         return dev->snapSpecial();
40     }
41 };
42 
43 // TODO: re-enable this when Raster methods are implemented
44 #if 0
45 DEF_TEST(SpecialImage_BitmapDevice, reporter) {
46     static const int kWidth = 100;
47     static const int kHeight = 90;
48 
49     SkImageInfo ii = SkImageInfo::MakeN32Premul(2*kWidth, 2*kHeight);
50 
51     sk_sp<SkBaseDevice> bmDev(SkBitmapDevice::Create(ii));
52 
53     SkBitmap bm;
54     bm.tryAllocN32Pixels(kWidth, kHeight);
55 
56     // Create a raster-backed special image from a raster-backed SkBitmap
57     sk_sp<SkSpecialImage> special = DeviceTestingAccess::MakeSpecial(bmDev.get(), bm);
58     SkASSERT(!special->isTextureBacked());
59     SkASSERT(kWidth == special->width());
60     SkASSERT(kHeight == special->height());
61     SkASSERT(bm.getGenerationID() == special->uniqueID());
62     SkASSERT(SkIRect::MakeWH(kWidth, kHeight) == special->subset());
63 
64     // Create a raster-backed special image from a raster-backed SkImage
65     sk_sp<SkImage> image(SkImage::MakeFromBitmap(bm));
66     special = DeviceTestingAccess::MakeSpecial(bmDev.get(), image.get());
67     SkASSERT(!special->isTextureBacked());
68     SkASSERT(kWidth == special->width());
69     SkASSERT(kHeight == special->height());
70     SkASSERT(bm.getGenerationID() == special->uniqueID());
71     SkASSERT(SkIRect::MakeWH(kWidth, kHeight) == special->subset());
72 
73     // Snap the device as a raster-backed special image
74     special = DeviceTestingAccess::SnapSpecial(bmDev.get());
75     SkASSERT(!special->isTextureBacked());
76     SkASSERT(2*kWidth == special->width());
77     SkASSERT(2*kHeight == special->height());
78     SkASSERT(SkIRect::MakeWH(2*kWidth, 2*kHeight) == special->subset());
79 }
80 #endif
81 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SpecialImage_GPUDevice,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)82 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SpecialImage_GPUDevice,
83                                        reporter,
84                                        ctxInfo,
85                                        CtsEnforcement::kApiLevel_T) {
86     auto dContext = ctxInfo.directContext();
87 
88     static const int kWidth = 100;
89     static const int kHeight = 90;
90 
91     SkImageInfo ii = SkImageInfo::MakeN32Premul(2*kWidth, 2*kHeight);
92 
93     auto device = dContext->priv().createDevice(skgpu::Budgeted::kNo,
94                                                 ii,
95                                                 SkBackingFit::kExact,
96                                                 1,
97                                                 GrMipmapped::kNo,
98                                                 GrProtected::kNo,
99                                                 kBottomLeft_GrSurfaceOrigin,
100                                                 SkSurfaceProps(),
101                                                 skgpu::v1::Device::InitContents::kClear);
102 
103     SkBitmap bm;
104     SkAssertResult(bm.tryAllocN32Pixels(kWidth, kHeight));
105 
106     // Create a gpu-backed special image from a raster-backed SkBitmap
107     sk_sp<SkSpecialImage> special = DeviceTestingAccess::MakeSpecial(device.get(), bm);
108     SkASSERT(special->isTextureBacked());
109     SkASSERT(kWidth == special->width());
110     SkASSERT(kHeight == special->height());
111     SkASSERT(bm.getGenerationID() == special->uniqueID());
112     SkASSERT(SkIRect::MakeWH(kWidth, kHeight) == special->subset());
113 
114     // Create a gpu-backed special image from a raster-backed SkImage
115     sk_sp<SkImage> image(bm.asImage());
116     special = DeviceTestingAccess::MakeSpecial(device.get(), image.get());
117     SkASSERT(special->isTextureBacked());
118     SkASSERT(kWidth == special->width());
119     SkASSERT(kHeight == special->height());
120     // TODO: Hmmm, this is a bit unexpected
121     SkASSERT(image->uniqueID() != special->uniqueID());
122     SkASSERT(SkIRect::MakeWH(kWidth, kHeight) == special->subset());
123 
124     // Create a gpu-backed special image from a gpu-backed SkImage
125     image = image->makeTextureImage(dContext);
126     special = DeviceTestingAccess::MakeSpecial(device.get(), image.get());
127     SkASSERT(special->isTextureBacked());
128     SkASSERT(kWidth == special->width());
129     SkASSERT(kHeight == special->height());
130     SkASSERT(image->uniqueID() == special->uniqueID());
131     SkASSERT(SkIRect::MakeWH(kWidth, kHeight) == special->subset());
132 
133     // Snap the device as a gpu-backed special image
134     special = DeviceTestingAccess::SnapSpecial(device.get());
135     SkASSERT(special->isTextureBacked());
136     SkASSERT(2*kWidth == special->width());
137     SkASSERT(2*kHeight == special->height());
138     SkASSERT(SkIRect::MakeWH(2*kWidth, 2*kHeight) == special->subset());
139 }
140