blob: 971f71d0fc179d2f9d5431baed90f23a634629cb [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
Brian Salomonbf6b9792019-08-21 09:38:10 -040033 auto rtc = ctx->priv().makeVulkanSecondaryCBRenderTargetContext(imageInfo, vkInfo, props);
Robert Phillipsb2adbef2019-07-02 16:33:05 -040034 SkASSERT(rtc->asSurfaceProxy()->isInstantiated());
Greg Danielb46add82019-01-02 14:51:29 -050035
Brian Salomonbf6b9792019-08-21 09:38:10 -040036 sk_sp<SkGpuDevice> device(
37 SkGpuDevice::Make(ctx, std::move(rtc), SkGpuDevice::kUninit_InitContents));
Greg Danielb46add82019-01-02 14:51:29 -050038 if (!device) {
39 return nullptr;
40 }
41
Greg Danielb085fa92019-03-05 16:55:12 -050042 return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
43 props));
Greg Danielb46add82019-01-02 14:51:29 -050044}
45
Greg Danielb085fa92019-03-05 16:55:12 -050046GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,
47 const SkSurfaceProps* props)
48 : fDevice(device)
49 , fProps(SkSurfacePropsCopyOrDefault(props)) {}
Greg Danielb46add82019-01-02 14:51:29 -050050
51GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
52 SkASSERT(!fDevice);
53 SkASSERT(!fCachedCanvas.get());
54}
55
56SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
57 if (!fCachedCanvas) {
58 fCachedCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(fDevice));
59 }
60 return fCachedCanvas.get();
61}
62
63void GrVkSecondaryCBDrawContext::flush() {
64 fDevice->flush();
65}
66
Greg Daniel3d92a492019-01-07 12:59:03 -050067bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
68 const GrBackendSemaphore waitSemaphores[]) {
69 return fDevice->wait(numSemaphores, waitSemaphores);
70}
71
Greg Danielb46add82019-01-02 14:51:29 -050072void GrVkSecondaryCBDrawContext::releaseResources() {
73 fCachedCanvas.reset();
74 fDevice.reset();
75}
76
Greg Danielb085fa92019-03-05 16:55:12 -050077bool GrVkSecondaryCBDrawContext::characterize(SkSurfaceCharacterization* characterization) const {
78 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
79 GrContext* ctx = fDevice->context();
80
Robert Phillipscf39f372019-09-03 10:29:20 -040081 size_t maxResourceBytes = ctx->getResourceCacheLimit();
Greg Danielb085fa92019-03-05 16:55:12 -050082
83 // We current don't support textured GrVkSecondaryCBDrawContexts.
84 SkASSERT(!rtc->asTextureProxy());
85
Brian Salomonbd3d8d32019-07-02 09:16:28 -040086 SkColorType ct = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
87 if (ct == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -050088 return false;
89 }
90
91 SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType,
92 rtc->colorSpaceInfo().refColorSpace());
93
Robert Phillipsb2adbef2019-07-02 16:33:05 -040094 GrBackendFormat format = rtc->asRenderTargetProxy()->backendFormat();
95
96 characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, format,
97 rtc->origin(), rtc->numSamples(),
98 SkSurfaceCharacterization::Textureable(false),
Greg Danielb085fa92019-03-05 16:55:12 -050099 SkSurfaceCharacterization::MipMapped(false),
100 SkSurfaceCharacterization::UsesGLFBO0(false),
101 SkSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
Robert Phillips3cd54322019-07-10 09:28:59 -0400102 GrProtected(rtc->asRenderTargetProxy()->isProtected()),
Greg Danielb085fa92019-03-05 16:55:12 -0500103 this->props());
104
105 return true;
106}
107
108bool GrVkSecondaryCBDrawContext::isCompatible(
109 const SkSurfaceCharacterization& characterization) const {
110 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
111 GrContext* ctx = fDevice->context();
112
113 if (!characterization.isValid()) {
114 return false;
115 }
116
117 if (!characterization.vulkanSecondaryCBCompatible()) {
118 return false;
119 }
120
121 // As long as the current state in the context allows for greater or equal resources,
122 // we allow the DDL to be replayed.
123 // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
Robert Phillipscf39f372019-09-03 10:29:20 -0400124 size_t maxResourceBytes = ctx->getResourceCacheLimit();
Greg Danielb085fa92019-03-05 16:55:12 -0500125
126 if (characterization.isTextureable()) {
127 // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
128 return false;
129 }
130
131 if (characterization.usesGLFBO0()) {
132 return false;
133 }
134
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400135 SkColorType rtColorType = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
136 if (rtColorType == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -0500137 return false;
138 }
139
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400140 GrBackendFormat rtcFormat = rtc->asRenderTargetProxy()->backendFormat();
Robert Phillips3cd54322019-07-10 09:28:59 -0400141 GrProtected isProtected = GrProtected(rtc->asRenderTargetProxy()->isProtected());
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400142
Greg Danielb085fa92019-03-05 16:55:12 -0500143 return characterization.contextInfo() && characterization.contextInfo()->priv().matches(ctx) &&
144 characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
145 characterization.origin() == rtc->origin() &&
Robert Phillipsb2adbef2019-07-02 16:33:05 -0400146 characterization.backendFormat() == rtcFormat &&
Greg Danielb085fa92019-03-05 16:55:12 -0500147 characterization.width() == rtc->width() &&
148 characterization.height() == rtc->height() &&
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400149 characterization.colorType() == rtColorType &&
Chris Dalton6ce447a2019-06-23 18:07:38 -0600150 characterization.sampleCount() == rtc->numSamples() &&
Greg Danielb085fa92019-03-05 16:55:12 -0500151 SkColorSpace::Equals(characterization.colorSpace(),
152 rtc->colorSpaceInfo().colorSpace()) &&
Robert Phillips3cd54322019-07-10 09:28:59 -0400153 characterization.isProtected() == isProtected &&
Greg Danielb085fa92019-03-05 16:55:12 -0500154 characterization.surfaceProps() == rtc->surfaceProps();
155}
156
157bool GrVkSecondaryCBDrawContext::draw(SkDeferredDisplayList* ddl) {
158 if (!ddl || !this->isCompatible(ddl->characterization())) {
159 return false;
160 }
161
162 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
163 GrContext* ctx = fDevice->context();
164
Chris Dalton6b498102019-08-01 14:14:52 -0600165 ctx->priv().copyRenderTasksFromDDL(ddl, rtc->asRenderTargetProxy());
Greg Danielb085fa92019-03-05 16:55:12 -0500166 return true;
167}
168
169