blob: 9ffbdd419e4b4cb3c45b40e71e6dbbb9cb4409ac [file] [log] [blame]
Greg Danielb46add82019-01-02 14:51:29 -05001/*
2 * Copyright 2019 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/vk/GrVkSecondaryCBDrawContext.h"
Greg Danielb46add82019-01-02 14:51:29 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkImageInfo.h"
11#include "include/core/SkSurfaceCharacterization.h"
12#include "include/gpu/GrContext.h"
13#include "include/gpu/vk/GrVkTypes.h"
14#include "include/private/SkDeferredDisplayList.h"
15#include "src/core/SkSurfacePriv.h"
16#include "src/gpu/GrContextPriv.h"
17#include "src/gpu/GrContextThreadSafeProxyPriv.h"
18#include "src/gpu/GrRenderTargetContext.h"
19#include "src/gpu/SkGpuDevice.h"
Greg Danielb46add82019-01-02 14:51:29 -050020
21sk_sp<GrVkSecondaryCBDrawContext> GrVkSecondaryCBDrawContext::Make(GrContext* ctx,
22 const SkImageInfo& imageInfo,
23 const GrVkDrawableInfo& vkInfo,
24 const SkSurfaceProps* props) {
25 if (!ctx) {
26 return nullptr;
27 }
28
Robert Phillips4217ea72019-01-30 13:08:28 -050029 if (ctx->backend() != GrBackendApi::kVulkan) {
Greg Danielb46add82019-01-02 14:51:29 -050030 return nullptr;
31 }
32
33 sk_sp<GrRenderTargetContext> rtc(
Robert Phillips9da87e02019-02-04 13:26:26 -050034 ctx->priv().makeVulkanSecondaryCBRenderTargetContext(imageInfo, vkInfo, props));
Robert Phillipsb2adbef2019-07-02 16:33:05 -040035 SkASSERT(rtc->asSurfaceProxy()->isInstantiated());
Greg Danielb46add82019-01-02 14:51:29 -050036
37 int width = rtc->width();
38 int height = rtc->height();
39
40 sk_sp<SkGpuDevice> device(SkGpuDevice::Make(ctx, std::move(rtc), width, height,
41 SkGpuDevice::kUninit_InitContents));
42 if (!device) {
43 return nullptr;
44 }
45
Greg Danielb085fa92019-03-05 16:55:12 -050046 return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
47 props));
Greg Danielb46add82019-01-02 14:51:29 -050048}
49
Greg Danielb085fa92019-03-05 16:55:12 -050050GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,
51 const SkSurfaceProps* props)
52 : fDevice(device)
53 , fProps(SkSurfacePropsCopyOrDefault(props)) {}
Greg Danielb46add82019-01-02 14:51:29 -050054
55GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
56 SkASSERT(!fDevice);
57 SkASSERT(!fCachedCanvas.get());
58}
59
60SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
61 if (!fCachedCanvas) {
62 fCachedCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(fDevice));
63 }
64 return fCachedCanvas.get();
65}
66
67void GrVkSecondaryCBDrawContext::flush() {
68 fDevice->flush();
69}
70
Greg Daniel3d92a492019-01-07 12:59:03 -050071bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
72 const GrBackendSemaphore waitSemaphores[]) {
73 return fDevice->wait(numSemaphores, waitSemaphores);
74}
75
Greg Danielb46add82019-01-02 14:51:29 -050076void GrVkSecondaryCBDrawContext::releaseResources() {
77 fCachedCanvas.reset();
78 fDevice.reset();
79}
80
Greg Danielb085fa92019-03-05 16:55:12 -050081bool GrVkSecondaryCBDrawContext::characterize(SkSurfaceCharacterization* characterization) const {
82 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
83 GrContext* ctx = fDevice->context();
84
85 int maxResourceCount;
86 size_t maxResourceBytes;
87 ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
88
89 // We current don't support textured GrVkSecondaryCBDrawContexts.
90 SkASSERT(!rtc->asTextureProxy());
91
Brian Salomonbd3d8d32019-07-02 09:16:28 -040092 SkColorType ct = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
93 if (ct == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -050094 return false;
95 }
96
97 SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType,
98 rtc->colorSpaceInfo().refColorSpace());
99
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400100 GrBackendFormat format = rtc->asRenderTargetProxy()->backendFormat();
101
102 characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, format,
103 rtc->origin(), rtc->numSamples(),
104 SkSurfaceCharacterization::Textureable(false),
Greg Danielb085fa92019-03-05 16:55:12 -0500105 SkSurfaceCharacterization::MipMapped(false),
106 SkSurfaceCharacterization::UsesGLFBO0(false),
107 SkSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
Robert Phillips3cd54322019-07-10 09:28:59 -0400108 GrProtected(rtc->asRenderTargetProxy()->isProtected()),
Greg Danielb085fa92019-03-05 16:55:12 -0500109 this->props());
110
111 return true;
112}
113
114bool GrVkSecondaryCBDrawContext::isCompatible(
115 const SkSurfaceCharacterization& characterization) const {
116 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
117 GrContext* ctx = fDevice->context();
118
119 if (!characterization.isValid()) {
120 return false;
121 }
122
123 if (!characterization.vulkanSecondaryCBCompatible()) {
124 return false;
125 }
126
127 // As long as the current state in the context allows for greater or equal resources,
128 // we allow the DDL to be replayed.
129 // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
130 int maxResourceCount;
131 size_t maxResourceBytes;
132 ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
133
134 if (characterization.isTextureable()) {
135 // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
136 return false;
137 }
138
139 if (characterization.usesGLFBO0()) {
140 return false;
141 }
142
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400143 SkColorType rtColorType = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
144 if (rtColorType == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -0500145 return false;
146 }
147
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400148 GrBackendFormat rtcFormat = rtc->asRenderTargetProxy()->backendFormat();
Robert Phillips3cd54322019-07-10 09:28:59 -0400149 GrProtected isProtected = GrProtected(rtc->asRenderTargetProxy()->isProtected());
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400150
Greg Danielb085fa92019-03-05 16:55:12 -0500151 return characterization.contextInfo() && characterization.contextInfo()->priv().matches(ctx) &&
152 characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
153 characterization.origin() == rtc->origin() &&
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400154 characterization.backendFormat() == rtcFormat &&
Greg Danielb085fa92019-03-05 16:55:12 -0500155 characterization.width() == rtc->width() &&
156 characterization.height() == rtc->height() &&
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400157 characterization.colorType() == rtColorType &&
Chris Dalton6ce447a2019-06-23 18:07:38 -0600158 characterization.sampleCount() == rtc->numSamples() &&
Greg Danielb085fa92019-03-05 16:55:12 -0500159 SkColorSpace::Equals(characterization.colorSpace(),
160 rtc->colorSpaceInfo().colorSpace()) &&
Robert Phillips3cd54322019-07-10 09:28:59 -0400161 characterization.isProtected() == isProtected &&
Greg Danielb085fa92019-03-05 16:55:12 -0500162 characterization.surfaceProps() == rtc->surfaceProps();
163}
164
165bool GrVkSecondaryCBDrawContext::draw(SkDeferredDisplayList* ddl) {
166 if (!ddl || !this->isCompatible(ddl->characterization())) {
167 return false;
168 }
169
170 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
171 GrContext* ctx = fDevice->context();
172
Chris Dalton6b498102019-08-01 14:14:52 -0600173 ctx->priv().copyRenderTasksFromDDL(ddl, rtc->asRenderTargetProxy());
Greg Danielb085fa92019-03-05 16:55:12 -0500174 return true;
175}
176
177