blob: 5de09e7baf3db0513b994b3c1ef9e807e01b374a [file] [log] [blame]
Brian Salomoncfe910d2017-07-06 16:40:18 -04001/*
2 * Copyright 2017 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/mock/GrMockBuffer.h"
9#include "src/gpu/mock/GrMockCaps.h"
10#include "src/gpu/mock/GrMockGpu.h"
11#include "src/gpu/mock/GrMockGpuCommandBuffer.h"
12#include "src/gpu/mock/GrMockStencilAttachment.h"
13#include "src/gpu/mock/GrMockTexture.h"
Mike Kleinde2244c2018-12-04 11:16:08 -050014#include <atomic>
Brian Salomoncfe910d2017-07-06 16:40:18 -040015
Brian Salomon8fe24272017-07-07 12:56:11 -040016int GrMockGpu::NextInternalTextureID() {
Mike Kleinde2244c2018-12-04 11:16:08 -050017 static std::atomic<int> nextID{1};
Chris Dalton351e80c2019-01-06 22:51:00 -070018 int id;
19 do {
20 id = nextID.fetch_add(1);
21 } while (0 == id); // Reserve 0 for an invalid ID.
22 return id;
Brian Salomon8fe24272017-07-07 12:56:11 -040023}
24
25int GrMockGpu::NextExternalTextureID() {
26 // We use negative ints for the "testing only external textures" so they can easily be
27 // identified when debugging.
Mike Kleinde2244c2018-12-04 11:16:08 -050028 static std::atomic<int> nextID{-1};
29 return nextID--;
Brian Salomon8fe24272017-07-07 12:56:11 -040030}
31
Brian Salomon0c51eea2018-03-09 17:02:09 -050032int GrMockGpu::NextInternalRenderTargetID() {
Mike Kleinde2244c2018-12-04 11:16:08 -050033 // We start off with large numbers to differentiate from texture IDs, even though they're
Brian Salomon0c51eea2018-03-09 17:02:09 -050034 // technically in a different space.
Mike Kleinde2244c2018-12-04 11:16:08 -050035 static std::atomic<int> nextID{SK_MaxS32};
36 return nextID--;
Brian Salomon0c51eea2018-03-09 17:02:09 -050037}
38
39int GrMockGpu::NextExternalRenderTargetID() {
40 // We use large negative ints for the "testing only external render targets" so they can easily
41 // be identified when debugging.
Mike Kleinde2244c2018-12-04 11:16:08 -050042 static std::atomic<int> nextID{SK_MinS32};
43 return nextID++;
Brian Salomon0c51eea2018-03-09 17:02:09 -050044}
45
Brian Salomon384fab42017-12-07 12:33:05 -050046sk_sp<GrGpu> GrMockGpu::Make(const GrMockOptions* mockOptions,
47 const GrContextOptions& contextOptions, GrContext* context) {
Greg Daniel02611d92017-07-25 10:05:01 -040048 static const GrMockOptions kDefaultOptions = GrMockOptions();
49 if (!mockOptions) {
50 mockOptions = &kDefaultOptions;
51 }
Brian Salomon384fab42017-12-07 12:33:05 -050052 return sk_sp<GrGpu>(new GrMockGpu(context, *mockOptions, contextOptions));
Greg Daniel02611d92017-07-25 10:05:01 -040053}
54
Robert Phillips5b5d84c2018-08-09 15:12:18 -040055GrGpuRTCommandBuffer* GrMockGpu::getCommandBuffer(
Ethan Nicholas56d19a52018-10-15 11:26:20 -040056 GrRenderTarget* rt, GrSurfaceOrigin origin, const SkRect& bounds,
Robert Phillips5b5d84c2018-08-09 15:12:18 -040057 const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
58 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) {
Greg Daniel500d58b2017-08-24 15:59:33 -040059 return new GrMockGpuRTCommandBuffer(this, rt, origin);
Brian Salomoncfe910d2017-07-06 16:40:18 -040060}
61
Robert Phillips5b5d84c2018-08-09 15:12:18 -040062GrGpuTextureCommandBuffer* GrMockGpu::getCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) {
Greg Daniel500d58b2017-08-24 15:59:33 -040063 return new GrMockGpuTextureCommandBuffer(texture, origin);
64}
65
Robert Phillips5b5d84c2018-08-09 15:12:18 -040066void GrMockGpu::submit(GrGpuCommandBuffer* buffer) {
67 if (buffer->asRTCommandBuffer()) {
68 this->submitCommandBuffer(
69 static_cast<GrMockGpuRTCommandBuffer*>(buffer->asRTCommandBuffer()));
70 }
71
72 delete buffer;
73}
Greg Daniel500d58b2017-08-24 15:59:33 -040074
75void GrMockGpu::submitCommandBuffer(const GrMockGpuRTCommandBuffer* cmdBuffer) {
Brian Salomoncfe910d2017-07-06 16:40:18 -040076 for (int i = 0; i < cmdBuffer->numDraws(); ++i) {
77 fStats.incNumDraws();
78 }
79}
80
81GrMockGpu::GrMockGpu(GrContext* context, const GrMockOptions& options,
82 const GrContextOptions& contextOptions)
Chris Dalton91ab1552018-04-18 13:24:25 -060083 : INHERITED(context)
84 , fMockOptions(options) {
Brian Salomoncfe910d2017-07-06 16:40:18 -040085 fCaps.reset(new GrMockCaps(contextOptions, options));
86}
87
Chris Daltonc3318f02019-07-19 14:20:53 -060088void GrMockGpu::querySampleLocations(GrRenderTarget* rt, SkTArray<SkPoint>* sampleLocations) {
89 sampleLocations->reset();
90 int numRemainingSamples = rt->numSamples();
91 while (numRemainingSamples > 0) {
92 // Use standard D3D sample locations.
93 switch (numRemainingSamples) {
94 case 0:
95 case 1:
96 sampleLocations->push_back().set(.5, .5);
97 break;
98 case 2:
99 sampleLocations->push_back().set(.75, .75);
100 sampleLocations->push_back().set(.25, .25);
101 break;
102 case 3:
103 case 4:
104 sampleLocations->push_back().set(.375, .125);
105 sampleLocations->push_back().set(.875, .375);
106 sampleLocations->push_back().set(.125, .625);
107 sampleLocations->push_back().set(.625, .875);
108 break;
109 case 5:
110 case 6:
111 case 7:
112 case 8:
113 sampleLocations->push_back().set(.5625, .3125);
114 sampleLocations->push_back().set(.4375, .6875);
115 sampleLocations->push_back().set(.8125, .5625);
116 sampleLocations->push_back().set(.3125, .1875);
117 sampleLocations->push_back().set(.1875, .8125);
118 sampleLocations->push_back().set(.0625, .4375);
119 sampleLocations->push_back().set(.6875, .4375);
120 sampleLocations->push_back().set(.4375, .0625);
121 break;
122 default:
123 sampleLocations->push_back().set(.5625, .5625);
124 sampleLocations->push_back().set(.4375, .3125);
125 sampleLocations->push_back().set(.3125, .6250);
126 sampleLocations->push_back().set(.2500, .4375);
127 sampleLocations->push_back().set(.1875, .3750);
128 sampleLocations->push_back().set(.6250, .8125);
129 sampleLocations->push_back().set(.8125, .6875);
130 sampleLocations->push_back().set(.6875, .1875);
131 sampleLocations->push_back().set(.3750, .8750);
132 sampleLocations->push_back().set(.5000, .0625);
133 sampleLocations->push_back().set(.2500, .1250);
134 sampleLocations->push_back().set(.1250, .2500);
135 sampleLocations->push_back().set(.0000, .5000);
136 sampleLocations->push_back().set(.4375, .2500);
137 sampleLocations->push_back().set(.8750, .4375);
138 sampleLocations->push_back().set(.0625, .0000);
139 break;
140 }
141 numRemainingSamples = rt->numSamples() - sampleLocations->count();
142 }
143}
144
Brian Salomonf2c2ba92019-07-17 09:59:59 -0400145sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400146 int renderTargetSampleCnt, SkBudgeted budgeted,
147 GrProtected isProtected, const GrMipLevel texels[],
148 int mipLevelCount) {
Chris Dalton91ab1552018-04-18 13:24:25 -0600149 if (fMockOptions.fFailTextureAllocations) {
150 return nullptr;
151 }
152
Greg Daniele877dce2019-07-11 10:52:43 -0400153 GrColorType ct = GrPixelConfigToColorType(desc.fConfig);
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400154 if (GrColorType::kUnknown == ct) {
155 return nullptr;
156 }
157
Greg Daniel0fc4d2d2017-10-12 11:23:36 -0400158 GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid
159 : GrMipMapsStatus::kNotAllocated;
Greg Daniele877dce2019-07-11 10:52:43 -0400160 GrMockTextureInfo texInfo(ct, NextInternalTextureID());
Brian Salomonf2c2ba92019-07-17 09:59:59 -0400161 if (renderable == GrRenderable::kYes) {
Greg Daniele877dce2019-07-11 10:52:43 -0400162 GrMockRenderTargetInfo rtInfo(ct, NextInternalRenderTargetID());
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400163 return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc,
164 renderTargetSampleCnt, isProtected,
Brian Salomone8a766b2019-07-19 14:24:36 -0400165 mipMapsStatus, texInfo, rtInfo));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400166 }
Brian Salomone8a766b2019-07-19 14:24:36 -0400167 return sk_sp<GrTexture>(
168 new GrMockTexture(this, budgeted, desc, isProtected, mipMapsStatus, texInfo));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400169}
170
Brian Salomonbb8dde82019-06-27 10:52:13 -0400171sk_sp<GrTexture> GrMockGpu::onCreateCompressedTexture(int width, int height,
172 SkImage::CompressionType compressionType,
173 SkBudgeted budgeted, const void* data) {
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400174 return nullptr;
Brian Salomonbb8dde82019-06-27 10:52:13 -0400175}
176
Robert Phillipsdd399802019-07-18 12:28:00 +0000177sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500178 GrWrapOwnership ownership,
179 GrWrapCacheable wrapType, GrIOType ioType) {
Robert Phillipsdd399802019-07-18 12:28:00 +0000180 GrMockTextureInfo info;
181 SkAssertResult(tex.getMockTextureInfo(&info));
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400182
Greg Daniel4684f822018-03-08 15:27:36 -0500183 GrSurfaceDesc desc;
184 desc.fWidth = tex.width();
185 desc.fHeight = tex.height();
Robert Phillipsdd399802019-07-18 12:28:00 +0000186 desc.fConfig = info.pixelConfig();
Greg Daniel4684f822018-03-08 15:27:36 -0500187
188 GrMipMapsStatus mipMapsStatus = tex.hasMipMaps() ? GrMipMapsStatus::kValid
189 : GrMipMapsStatus::kNotAllocated;
Brian Salomone8a766b2019-07-19 14:24:36 -0400190 auto isProtected = GrProtected(tex.isProtected());
191 return sk_sp<GrTexture>(
192 new GrMockTexture(this, desc, isProtected, mipMapsStatus, info, wrapType, ioType));
Greg Daniel4684f822018-03-08 15:27:36 -0500193}
194
Brian Salomon0c51eea2018-03-09 17:02:09 -0500195sk_sp<GrTexture> GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,
196 int sampleCnt,
Robert Phillips0902c982019-07-16 07:47:56 -0400197 GrColorType colorType,
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500198 GrWrapOwnership ownership,
199 GrWrapCacheable cacheable) {
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400200 GrMockTextureInfo texInfo;
201 SkAssertResult(tex.getMockTextureInfo(&texInfo));
202
Robert Phillips0902c982019-07-16 07:47:56 -0400203 SkASSERT(colorType == texInfo.fColorType);
Brian Salomon0c51eea2018-03-09 17:02:09 -0500204 GrSurfaceDesc desc;
Brian Salomon0c51eea2018-03-09 17:02:09 -0500205 desc.fWidth = tex.width();
206 desc.fHeight = tex.height();
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400207 desc.fConfig = texInfo.pixelConfig();
Brian Salomon0c51eea2018-03-09 17:02:09 -0500208
209 GrMipMapsStatus mipMapsStatus =
210 tex.hasMipMaps() ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
211
Brian Salomon0c51eea2018-03-09 17:02:09 -0500212 // The client gave us the texture ID but we supply the render target ID.
Greg Daniele877dce2019-07-11 10:52:43 -0400213 GrMockRenderTargetInfo rtInfo(texInfo.fColorType, NextInternalRenderTargetID());
Brian Salomon0c51eea2018-03-09 17:02:09 -0500214
Brian Salomone8a766b2019-07-19 14:24:36 -0400215 auto isProtected = GrProtected(tex.isProtected());
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400216 return sk_sp<GrTexture>(new GrMockTextureRenderTarget(
217 this, desc, sampleCnt, isProtected, mipMapsStatus, texInfo, rtInfo, cacheable));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500218}
219
Robert Phillipsdd399802019-07-18 12:28:00 +0000220sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& rt) {
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400221 GrMockRenderTargetInfo info;
222 SkAssertResult(rt.getMockRenderTargetInfo(&info));
223
Brian Salomon0c51eea2018-03-09 17:02:09 -0500224 GrSurfaceDesc desc;
Brian Salomon0c51eea2018-03-09 17:02:09 -0500225 desc.fWidth = rt.width();
226 desc.fHeight = rt.height();
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400227 desc.fConfig = info.pixelConfig();
Brian Salomon0c51eea2018-03-09 17:02:09 -0500228
Brian Salomone8a766b2019-07-19 14:24:36 -0400229 auto isProtected = GrProtected(rt.isProtected());
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400230 return sk_sp<GrRenderTarget>(new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc,
231 rt.sampleCnt(), isProtected, info));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500232}
233
234sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
Robert Phillipsdd399802019-07-18 12:28:00 +0000235 int sampleCnt) {
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400236 GrMockTextureInfo texInfo;
237 SkAssertResult(tex.getMockTextureInfo(&texInfo));
238
Brian Salomon0c51eea2018-03-09 17:02:09 -0500239 GrSurfaceDesc desc;
Brian Salomon0c51eea2018-03-09 17:02:09 -0500240 desc.fWidth = tex.width();
241 desc.fHeight = tex.height();
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400242 desc.fConfig = texInfo.pixelConfig();
Brian Salomon0c51eea2018-03-09 17:02:09 -0500243
Brian Salomon0c51eea2018-03-09 17:02:09 -0500244 // The client gave us the texture ID but we supply the render target ID.
Greg Daniele877dce2019-07-11 10:52:43 -0400245 GrMockRenderTargetInfo rtInfo(texInfo.fColorType, NextInternalRenderTargetID());
Brian Salomon0c51eea2018-03-09 17:02:09 -0500246
Brian Salomone8a766b2019-07-19 14:24:36 -0400247 auto isProtected = GrProtected(tex.isProtected());
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400248 return sk_sp<GrRenderTarget>(new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc,
249 sampleCnt, isProtected, rtInfo));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500250}
251
Brian Salomondbf70722019-02-07 11:31:24 -0500252sk_sp<GrGpuBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType type,
253 GrAccessPattern accessPattern, const void*) {
254 return sk_sp<GrGpuBuffer>(new GrMockBuffer(this, sizeInBytes, type, accessPattern));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400255}
256
Chris Daltoneffee202019-07-01 22:28:03 -0600257GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(
258 const GrRenderTarget* rt, int width, int height, int numStencilSamples) {
259 SkASSERT(numStencilSamples == rt->numSamples());
Brian Salomoncfe910d2017-07-06 16:40:18 -0400260 static constexpr int kBits = 8;
261 fStats.incStencilAttachmentCreates();
Chris Dalton6ce447a2019-06-23 18:07:38 -0600262 return new GrMockStencilAttachment(this, width, height, kBits, rt->numSamples());
Brian Salomoncfe910d2017-07-06 16:40:18 -0400263}
Brian Salomon8fe24272017-07-07 12:56:11 -0400264
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400265GrBackendTexture GrMockGpu::createBackendTexture(int w, int h,
266 const GrBackendFormat& format,
267 GrMipMapped mipMapped,
268 GrRenderable /* renderable */,
269 const void* /* pixels */,
Robert Phillips459b2952019-05-23 09:38:27 -0400270 size_t /* rowBytes */,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400271 const SkColor4f* /* color */,
272 GrProtected /* isProtected */) {
Robert Phillips646f6372018-09-25 09:31:10 -0400273
Greg Daniele877dce2019-07-11 10:52:43 -0400274 if (!format.getMockColorType()) {
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400275 return GrBackendTexture(); // invalid;
276 }
277
Greg Daniele877dce2019-07-11 10:52:43 -0400278 if (!this->caps()->isFormatTexturable(*format.getMockColorType(), format)) {
Robert Phillips9dbcdcc2019-05-13 10:40:06 -0400279 return GrBackendTexture(); // invalid
280 }
281
Greg Daniele877dce2019-07-11 10:52:43 -0400282 GrMockTextureInfo info(*format.getMockColorType(), NextExternalTextureID());
Robert Phillips646f6372018-09-25 09:31:10 -0400283
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500284 fOutstandingTestingOnlyTextureIDs.add(info.fID);
Brian Salomon0c51eea2018-03-09 17:02:09 -0500285 return GrBackendTexture(w, h, mipMapped, info);
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500286}
287
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400288void GrMockGpu::deleteBackendTexture(const GrBackendTexture& tex) {
Robert Phillipsf0ced622019-05-16 09:06:25 -0400289 SkASSERT(GrBackendApi::kMock == tex.backend());
290
291 GrMockTextureInfo info;
292 if (tex.getMockTextureInfo(&info)) {
293 fOutstandingTestingOnlyTextureIDs.remove(info.fID);
294 }
295}
296
297#if GR_TEST_UTILS
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500298bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400299 SkASSERT(GrBackendApi::kMock == tex.backend());
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500300
Greg Daniel52e16d92018-04-10 09:34:07 -0400301 GrMockTextureInfo info;
302 if (!tex.getMockTextureInfo(&info)) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500303 return false;
304 }
305
Greg Daniel52e16d92018-04-10 09:34:07 -0400306 return fOutstandingTestingOnlyTextureIDs.contains(info.fID);
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500307}
308
Brian Salomon0c51eea2018-03-09 17:02:09 -0500309GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(int w, int h,
Brian Osman2d010b62018-08-09 10:55:09 -0400310 GrColorType colorType) {
Greg Daniele877dce2019-07-11 10:52:43 -0400311 GrMockRenderTargetInfo info(colorType, NextExternalRenderTargetID());
Brian Salomon0c51eea2018-03-09 17:02:09 -0500312 static constexpr int kSampleCnt = 1;
313 static constexpr int kStencilBits = 8;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400314 return GrBackendRenderTarget(w, h, kSampleCnt, kStencilBits, info);
Brian Salomonf865b052018-03-09 09:01:53 -0500315}
316
317void GrMockGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {}
318#endif