blob: 37466bb4ee2718545e9993a86263b7a3268c527b [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
88sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Brian Salomon58389b92018-03-07 13:01:25 -050089 const GrMipLevel texels[], int mipLevelCount) {
Chris Dalton91ab1552018-04-18 13:24:25 -060090 if (fMockOptions.fFailTextureAllocations) {
91 return nullptr;
92 }
93
Greg Daniel0fc4d2d2017-10-12 11:23:36 -040094 GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid
95 : GrMipMapsStatus::kNotAllocated;
Brian Salomon0c51eea2018-03-09 17:02:09 -050096 GrMockTextureInfo texInfo;
97 texInfo.fConfig = desc.fConfig;
98 texInfo.fID = NextInternalTextureID();
Brian Salomoncfe910d2017-07-06 16:40:18 -040099 if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
Brian Salomon0c51eea2018-03-09 17:02:09 -0500100 GrMockRenderTargetInfo rtInfo;
101 rtInfo.fConfig = desc.fConfig;
102 rtInfo.fID = NextInternalRenderTargetID();
103 return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc, mipMapsStatus,
104 texInfo, rtInfo));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400105 }
Brian Salomon0c51eea2018-03-09 17:02:09 -0500106 return sk_sp<GrTexture>(new GrMockTexture(this, budgeted, desc, mipMapsStatus, texInfo));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400107}
108
Brian Salomonbb8dde82019-06-27 10:52:13 -0400109sk_sp<GrTexture> GrMockGpu::onCreateCompressedTexture(int width, int height,
110 SkImage::CompressionType compressionType,
111 SkBudgeted budgeted, const void* data) {
112 if (fMockOptions.fFailTextureAllocations) {
113 return nullptr;
114 }
115 GrBackendFormat format = this->caps()->getBackendFormatFromCompressionType(compressionType);
116
117 GrMockTextureInfo texInfo;
118 texInfo.fConfig = *format.getMockFormat();
119 texInfo.fID = NextInternalTextureID();
120 GrSurfaceDesc desc;
121 desc.fConfig = texInfo.fConfig;
122 desc.fWidth = width;
123 desc.fHeight = height;
124 return sk_sp<GrTexture>(
125 new GrMockTexture(this, budgeted, desc, GrMipMapsStatus::kNotAllocated, texInfo));
126}
127
Greg Daniel4684f822018-03-08 15:27:36 -0500128sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500129 GrWrapOwnership ownership,
130 GrWrapCacheable wrapType, GrIOType ioType) {
Greg Daniel4684f822018-03-08 15:27:36 -0500131 GrSurfaceDesc desc;
132 desc.fWidth = tex.width();
133 desc.fHeight = tex.height();
Greg Daniel52e16d92018-04-10 09:34:07 -0400134
135 GrMockTextureInfo info;
136 SkAssertResult(tex.getMockTextureInfo(&info));
Greg Daniel4684f822018-03-08 15:27:36 -0500137 desc.fConfig = info.fConfig;
138
139 GrMipMapsStatus mipMapsStatus = tex.hasMipMaps() ? GrMipMapsStatus::kValid
140 : GrMipMapsStatus::kNotAllocated;
141
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500142 return sk_sp<GrTexture>(new GrMockTexture(this, desc, mipMapsStatus, info, wrapType, ioType));
Greg Daniel4684f822018-03-08 15:27:36 -0500143}
144
Brian Salomon0c51eea2018-03-09 17:02:09 -0500145sk_sp<GrTexture> GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,
146 int sampleCnt,
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500147 GrWrapOwnership ownership,
148 GrWrapCacheable cacheable) {
Brian Salomon0c51eea2018-03-09 17:02:09 -0500149 GrSurfaceDesc desc;
150 desc.fFlags = kRenderTarget_GrSurfaceFlag;
151 desc.fWidth = tex.width();
152 desc.fHeight = tex.height();
Greg Daniel52e16d92018-04-10 09:34:07 -0400153
154 GrMockTextureInfo texInfo;
155 SkAssertResult(tex.getMockTextureInfo(&texInfo));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500156 desc.fConfig = texInfo.fConfig;
157
158 GrMipMapsStatus mipMapsStatus =
159 tex.hasMipMaps() ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
160
161 GrMockRenderTargetInfo rtInfo;
162 rtInfo.fConfig = texInfo.fConfig;
163 // The client gave us the texture ID but we supply the render target ID.
164 rtInfo.fID = NextInternalRenderTargetID();
165
166 return sk_sp<GrTexture>(
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500167 new GrMockTextureRenderTarget(this, desc, mipMapsStatus, texInfo, rtInfo, cacheable));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500168}
169
170sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& rt) {
171 GrSurfaceDesc desc;
172 desc.fFlags = kRenderTarget_GrSurfaceFlag;
173 desc.fWidth = rt.width();
174 desc.fHeight = rt.height();
Greg Daniel323fbcf2018-04-10 13:46:30 -0400175
176 GrMockRenderTargetInfo info;
177 SkAssertResult(rt.getMockRenderTargetInfo(&info));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500178 desc.fConfig = info.fConfig;
179
180 return sk_sp<GrRenderTarget>(
181 new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, info));
182}
183
184sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
185 int sampleCnt) {
186 GrSurfaceDesc desc;
187 desc.fFlags = kRenderTarget_GrSurfaceFlag;
188 desc.fWidth = tex.width();
189 desc.fHeight = tex.height();
Greg Daniel52e16d92018-04-10 09:34:07 -0400190
191 GrMockTextureInfo texInfo;
192 SkAssertResult(tex.getMockTextureInfo(&texInfo));
Brian Salomon0c51eea2018-03-09 17:02:09 -0500193 desc.fConfig = texInfo.fConfig;
194 desc.fSampleCnt = sampleCnt;
195
196 GrMockRenderTargetInfo rtInfo;
197 rtInfo.fConfig = texInfo.fConfig;
198 // The client gave us the texture ID but we supply the render target ID.
199 rtInfo.fID = NextInternalRenderTargetID();
200
201 return sk_sp<GrRenderTarget>(
202 new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, rtInfo));
203}
204
Brian Salomondbf70722019-02-07 11:31:24 -0500205sk_sp<GrGpuBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType type,
206 GrAccessPattern accessPattern, const void*) {
207 return sk_sp<GrGpuBuffer>(new GrMockBuffer(this, sizeInBytes, type, accessPattern));
Brian Salomoncfe910d2017-07-06 16:40:18 -0400208}
209
Chris Daltoneffee202019-07-01 22:28:03 -0600210GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(
211 const GrRenderTarget* rt, int width, int height, int numStencilSamples) {
212 SkASSERT(numStencilSamples == rt->numSamples());
Brian Salomoncfe910d2017-07-06 16:40:18 -0400213 static constexpr int kBits = 8;
214 fStats.incStencilAttachmentCreates();
Chris Dalton6ce447a2019-06-23 18:07:38 -0600215 return new GrMockStencilAttachment(this, width, height, kBits, rt->numSamples());
Brian Salomoncfe910d2017-07-06 16:40:18 -0400216}
Brian Salomon8fe24272017-07-07 12:56:11 -0400217
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400218GrBackendTexture GrMockGpu::createBackendTexture(int w, int h,
219 const GrBackendFormat& format,
220 GrMipMapped mipMapped,
221 GrRenderable /* renderable */,
222 const void* /* pixels */,
Robert Phillips459b2952019-05-23 09:38:27 -0400223 size_t /* rowBytes */,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400224 const SkColor4f* /* color */,
225 GrProtected /* isProtected */) {
Robert Phillips646f6372018-09-25 09:31:10 -0400226
Robert Phillips9dbcdcc2019-05-13 10:40:06 -0400227 const GrPixelConfig* pixelConfig = format.getMockFormat();
228 if (!pixelConfig) {
229 return GrBackendTexture(); // invalid
230 }
231
232 if (!this->caps()->isConfigTexturable(*pixelConfig)) {
Robert Phillips646f6372018-09-25 09:31:10 -0400233 return GrBackendTexture(); // invalid
234 }
235
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500236 GrMockTextureInfo info;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -0400237 info.fConfig = *pixelConfig;
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500238 info.fID = NextExternalTextureID();
239 fOutstandingTestingOnlyTextureIDs.add(info.fID);
Brian Salomon0c51eea2018-03-09 17:02:09 -0500240 return GrBackendTexture(w, h, mipMapped, info);
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500241}
242
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400243void GrMockGpu::deleteBackendTexture(const GrBackendTexture& tex) {
Robert Phillipsf0ced622019-05-16 09:06:25 -0400244 SkASSERT(GrBackendApi::kMock == tex.backend());
245
246 GrMockTextureInfo info;
247 if (tex.getMockTextureInfo(&info)) {
248 fOutstandingTestingOnlyTextureIDs.remove(info.fID);
249 }
250}
251
252#if GR_TEST_UTILS
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500253bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400254 SkASSERT(GrBackendApi::kMock == tex.backend());
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500255
Greg Daniel52e16d92018-04-10 09:34:07 -0400256 GrMockTextureInfo info;
257 if (!tex.getMockTextureInfo(&info)) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500258 return false;
259 }
260
Greg Daniel52e16d92018-04-10 09:34:07 -0400261 return fOutstandingTestingOnlyTextureIDs.contains(info.fID);
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500262}
263
Brian Salomon0c51eea2018-03-09 17:02:09 -0500264GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(int w, int h,
Brian Osman2d010b62018-08-09 10:55:09 -0400265 GrColorType colorType) {
266 auto config = GrColorTypeToPixelConfig(colorType, GrSRGBEncoded::kNo);
Brian Salomon0c51eea2018-03-09 17:02:09 -0500267 if (kUnknown_GrPixelConfig == config) {
268 return {};
269 }
270 GrMockRenderTargetInfo info = {config, NextExternalRenderTargetID()};
271 static constexpr int kSampleCnt = 1;
272 static constexpr int kStencilBits = 8;
273 return {w, h, kSampleCnt, kStencilBits, info};
Brian Salomonf865b052018-03-09 09:01:53 -0500274}
275
276void GrMockGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {}
277#endif