blob: 3772292b28cf414ac54ad825c97b04c0ad2e7de6 [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));
Greg Danielb46add82019-01-02 14:51:29 -050035
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
Greg Danielb085fa92019-03-05 16:55:12 -050045 return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
46 props));
Greg Danielb46add82019-01-02 14:51:29 -050047}
48
Greg Danielb085fa92019-03-05 16:55:12 -050049GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,
50 const SkSurfaceProps* props)
51 : fDevice(device)
52 , fProps(SkSurfacePropsCopyOrDefault(props)) {}
Greg Danielb46add82019-01-02 14:51:29 -050053
54GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
55 SkASSERT(!fDevice);
56 SkASSERT(!fCachedCanvas.get());
57}
58
59SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
60 if (!fCachedCanvas) {
61 fCachedCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(fDevice));
62 }
63 return fCachedCanvas.get();
64}
65
66void GrVkSecondaryCBDrawContext::flush() {
67 fDevice->flush();
68}
69
Greg Daniel3d92a492019-01-07 12:59:03 -050070bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
71 const GrBackendSemaphore waitSemaphores[]) {
72 return fDevice->wait(numSemaphores, waitSemaphores);
73}
74
Greg Danielb46add82019-01-02 14:51:29 -050075void GrVkSecondaryCBDrawContext::releaseResources() {
76 fCachedCanvas.reset();
77 fDevice.reset();
78}
79
Greg Danielb085fa92019-03-05 16:55:12 -050080bool 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
Brian Salomonbd3d8d32019-07-02 09:16:28 -040091 SkColorType ct = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
92 if (ct == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -050093 return false;
94 }
95
96 SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType,
97 rtc->colorSpaceInfo().refColorSpace());
98
Brian Salomonbd3d8d32019-07-02 09:16:28 -040099 GrPixelConfig config = rtc->asSurfaceProxy()->config();
100 characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, rtc->origin(), config,
101 rtc->numSamples(), SkSurfaceCharacterization::Textureable(false),
Greg Danielb085fa92019-03-05 16:55:12 -0500102 SkSurfaceCharacterization::MipMapped(false),
103 SkSurfaceCharacterization::UsesGLFBO0(false),
104 SkSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
105 this->props());
106
107 return true;
108}
109
110bool GrVkSecondaryCBDrawContext::isCompatible(
111 const SkSurfaceCharacterization& characterization) const {
112 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
113 GrContext* ctx = fDevice->context();
114
115 if (!characterization.isValid()) {
116 return false;
117 }
118
119 if (!characterization.vulkanSecondaryCBCompatible()) {
120 return false;
121 }
122
123 // As long as the current state in the context allows for greater or equal resources,
124 // we allow the DDL to be replayed.
125 // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
126 int maxResourceCount;
127 size_t maxResourceBytes;
128 ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
129
130 if (characterization.isTextureable()) {
131 // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
132 return false;
133 }
134
135 if (characterization.usesGLFBO0()) {
136 return false;
137 }
138
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400139 SkColorType rtColorType = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
140 if (rtColorType == kUnknown_SkColorType) {
Greg Danielb085fa92019-03-05 16:55:12 -0500141 return false;
142 }
143
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400144 GrPixelConfig config = rtc->asSurfaceProxy()->config();
Greg Danielb085fa92019-03-05 16:55:12 -0500145 return characterization.contextInfo() && characterization.contextInfo()->priv().matches(ctx) &&
146 characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
147 characterization.origin() == rtc->origin() &&
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400148 characterization.config() == config &&
Greg Danielb085fa92019-03-05 16:55:12 -0500149 characterization.width() == rtc->width() &&
150 characterization.height() == rtc->height() &&
Brian Salomonbd3d8d32019-07-02 09:16:28 -0400151 characterization.colorType() == rtColorType &&
Chris Dalton6ce447a2019-06-23 18:07:38 -0600152 characterization.sampleCount() == rtc->numSamples() &&
Greg Danielb085fa92019-03-05 16:55:12 -0500153 SkColorSpace::Equals(characterization.colorSpace(),
154 rtc->colorSpaceInfo().colorSpace()) &&
155 characterization.surfaceProps() == rtc->surfaceProps();
156}
157
158bool GrVkSecondaryCBDrawContext::draw(SkDeferredDisplayList* ddl) {
159 if (!ddl || !this->isCompatible(ddl->characterization())) {
160 return false;
161 }
162
163 GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
164 GrContext* ctx = fDevice->context();
165
166 ctx->priv().copyOpListsFromDDL(ddl, rtc->asRenderTargetProxy());
167 return true;
168}
169
170