• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "vk/GrVkSecondaryCBDrawContext.h"
9 
10 #include "GrContext.h"
11 #include "GrContextPriv.h"
12 #include "GrContextThreadSafeProxyPriv.h"
13 #include "GrRenderTargetContext.h"
14 #include "SkDeferredDisplayList.h"
15 #include "SkGpuDevice.h"
16 #include "SkImageInfo.h"
17 #include "SkSurfaceCharacterization.h"
18 #include "SkSurfacePriv.h"
19 #include "vk/GrVkTypes.h"
20 
Make(GrContext * ctx,const SkImageInfo & imageInfo,const GrVkDrawableInfo & vkInfo,const SkSurfaceProps * props)21 sk_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 
29     if (ctx->backend() != GrBackendApi::kVulkan) {
30         return nullptr;
31     }
32 
33     sk_sp<GrRenderTargetContext> rtc(
34             ctx->priv().makeVulkanSecondaryCBRenderTargetContext(imageInfo, vkInfo, props));
35 
36     int width = rtc->width();
37     int height = rtc->height();
38 
39     sk_sp<SkGpuDevice> device(SkGpuDevice::Make(ctx, std::move(rtc), width, height,
40                                                 SkGpuDevice::kUninit_InitContents));
41     if (!device) {
42         return nullptr;
43     }
44 
45     return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
46                                                                             props));
47 }
48 
GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,const SkSurfaceProps * props)49 GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,
50                                                        const SkSurfaceProps* props)
51     : fDevice(device)
52     , fProps(SkSurfacePropsCopyOrDefault(props)) {}
53 
~GrVkSecondaryCBDrawContext()54 GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
55     SkASSERT(!fDevice);
56     SkASSERT(!fCachedCanvas.get());
57 }
58 
getCanvas()59 SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
60     if (!fCachedCanvas) {
61         fCachedCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(fDevice));
62     }
63     return fCachedCanvas.get();
64 }
65 
flush()66 void GrVkSecondaryCBDrawContext::flush() {
67     fDevice->flush();
68 }
69 
wait(int numSemaphores,const GrBackendSemaphore waitSemaphores[])70 bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
71                                       const GrBackendSemaphore waitSemaphores[]) {
72     return fDevice->wait(numSemaphores, waitSemaphores);
73 }
74 
releaseResources()75 void GrVkSecondaryCBDrawContext::releaseResources() {
76     fCachedCanvas.reset();
77     fDevice.reset();
78 }
79 
characterize(SkSurfaceCharacterization * characterization) const80 bool GrVkSecondaryCBDrawContext::characterize(SkSurfaceCharacterization* characterization) const {
81     GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
82     GrContext* ctx = fDevice->context();
83 
84     int maxResourceCount;
85     size_t maxResourceBytes;
86     ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
87 
88     // We current don't support textured GrVkSecondaryCBDrawContexts.
89     SkASSERT(!rtc->asTextureProxy());
90 
91     // TODO: the addition of colorType to the surfaceContext should remove this calculation
92     SkColorType ct;
93     if (!GrPixelConfigToColorType(rtc->colorSpaceInfo().config(), &ct)) {
94         return false;
95     }
96 
97     SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType,
98                                        rtc->colorSpaceInfo().refColorSpace());
99 
100     characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, rtc->origin(),
101                           rtc->colorSpaceInfo().config(), rtc->fsaaType(), rtc->numStencilSamples(),
102                           SkSurfaceCharacterization::Textureable(false),
103                           SkSurfaceCharacterization::MipMapped(false),
104                           SkSurfaceCharacterization::UsesGLFBO0(false),
105                           SkSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
106                           this->props());
107 
108     return true;
109 }
110 
isCompatible(const SkSurfaceCharacterization & characterization) const111 bool GrVkSecondaryCBDrawContext::isCompatible(
112         const SkSurfaceCharacterization& characterization) const {
113     GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
114     GrContext* ctx = fDevice->context();
115 
116     if (!characterization.isValid()) {
117         return false;
118     }
119 
120     if (!characterization.vulkanSecondaryCBCompatible()) {
121         return false;
122     }
123 
124     // As long as the current state in the context allows for greater or equal resources,
125     // we allow the DDL to be replayed.
126     // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
127     int maxResourceCount;
128     size_t maxResourceBytes;
129     ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
130 
131     if (characterization.isTextureable()) {
132         // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
133         return false;
134     }
135 
136     if (characterization.usesGLFBO0()) {
137         return false;
138     }
139 
140     // TODO: the addition of colorType to the surfaceContext should remove this calculation
141     SkColorType rtcColorType;
142     if (!GrPixelConfigToColorType(rtc->colorSpaceInfo().config(), &rtcColorType)) {
143         return false;
144     }
145 
146     return characterization.contextInfo() && characterization.contextInfo()->priv().matches(ctx) &&
147            characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
148            characterization.origin() == rtc->origin() &&
149            characterization.config() == rtc->colorSpaceInfo().config() &&
150            characterization.width() == rtc->width() &&
151            characterization.height() == rtc->height() &&
152            characterization.colorType() == rtcColorType &&
153            characterization.fsaaType() == rtc->fsaaType() &&
154            characterization.stencilCount() == rtc->numStencilSamples() &&
155            SkColorSpace::Equals(characterization.colorSpace(),
156                                 rtc->colorSpaceInfo().colorSpace()) &&
157            characterization.surfaceProps() == rtc->surfaceProps();
158 }
159 
draw(SkDeferredDisplayList * ddl)160 bool GrVkSecondaryCBDrawContext::draw(SkDeferredDisplayList* ddl) {
161     if (!ddl || !this->isCompatible(ddl->characterization())) {
162         return false;
163     }
164 
165     GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
166     GrContext* ctx = fDevice->context();
167 
168     ctx->priv().copyOpListsFromDDL(ddl, rtc->asRenderTargetProxy());
169     return true;
170 }
171 
172 
173