Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 1 | /* |
| 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 | |
| 8 | #include "SkDeferredDisplayListRecorder.h" |
| 9 | |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 10 | #include "SkDeferredDisplayList.h" |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 11 | #include "SkSurface.h" |
| 12 | #include "SkSurfaceCharacterization.h" |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 13 | |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 14 | #if !SK_SUPPORT_GPU |
| 15 | SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&) {} |
| 16 | |
| 17 | SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {} |
| 18 | |
| 19 | bool SkDeferredDisplayListRecorder::init() { return false; } |
| 20 | |
| 21 | SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { return nullptr; } |
| 22 | |
| 23 | std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { return nullptr; } |
| 24 | |
| 25 | sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture( |
| 26 | const GrBackendFormat& backendFormat, |
| 27 | int width, |
| 28 | int height, |
| 29 | GrMipMapped mipMapped, |
| 30 | GrSurfaceOrigin origin, |
| 31 | SkColorType colorType, |
| 32 | SkAlphaType alphaType, |
| 33 | sk_sp<SkColorSpace> colorSpace, |
| 34 | TextureFulfillProc textureFulfillProc, |
| 35 | TextureReleaseProc textureReleaseProc, |
| 36 | TextureContext textureContext) { |
| 37 | return nullptr; |
| 38 | } |
| 39 | |
| 40 | #else |
| 41 | |
| 42 | #include "GrContextPriv.h" |
| 43 | #include "GrProxyProvider.h" |
| 44 | #include "GrTexture.h" |
| 45 | |
| 46 | #include "SkGr.h" |
| 47 | #include "SkImage_Gpu.h" |
| 48 | #include "SkSurface_Gpu.h" |
| 49 | |
| 50 | SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization& c) |
| 51 | : fCharacterization(c) { |
| 52 | if (fCharacterization.isValid()) { |
| 53 | fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo()); |
| 54 | } |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 55 | } |
| 56 | |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 57 | SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() { |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 58 | if (fContext) { |
| 59 | auto proxyProvider = fContext->contextPriv().proxyProvider(); |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 60 | |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 61 | // DDL TODO: Remove this. DDL contexts should allow for deletion while still having live |
| 62 | // uniquely keyed proxies. |
| 63 | proxyProvider->removeAllUniqueKeys(); |
| 64 | } |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 68 | bool SkDeferredDisplayListRecorder::init() { |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 69 | SkASSERT(fContext); |
| 70 | SkASSERT(!fLazyProxyData); |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 71 | SkASSERT(!fSurface); |
| 72 | |
Robert Phillips | fc711a2 | 2018-02-13 17:03:00 -0500 | [diff] [blame] | 73 | if (!fCharacterization.isValid()) { |
| 74 | return false; |
| 75 | } |
| 76 | |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 77 | fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>( |
| 78 | new SkDeferredDisplayList::LazyProxyData); |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 79 | |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 80 | auto proxyProvider = fContext->contextPriv().proxyProvider(); |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 81 | |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 82 | GrSurfaceDesc desc; |
| 83 | desc.fFlags = kRenderTarget_GrSurfaceFlag; |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 84 | desc.fWidth = fCharacterization.width(); |
| 85 | desc.fHeight = fCharacterization.height(); |
| 86 | desc.fConfig = fCharacterization.config(); |
| 87 | desc.fSampleCnt = fCharacterization.stencilCount(); |
| 88 | |
| 89 | sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData; |
| 90 | |
| 91 | // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy |
Robert Phillips | e8fabb2 | 2018-02-04 14:33:21 -0500 | [diff] [blame] | 92 | // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 93 | // DDL is being replayed into. |
| 94 | |
Robert Phillips | e8fabb2 | 2018-02-04 14:33:21 -0500 | [diff] [blame] | 95 | sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( |
Brian Salomon | f777897 | 2018-03-08 10:13:17 -0500 | [diff] [blame] | 96 | [lazyProxyData](GrResourceProvider* resourceProvider) { |
Robert Phillips | 83373a8 | 2018-02-14 07:35:32 -0500 | [diff] [blame] | 97 | if (!resourceProvider) { |
| 98 | return sk_sp<GrSurface>(); |
| 99 | } |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 100 | |
Robert Phillips | 83373a8 | 2018-02-14 07:35:32 -0500 | [diff] [blame] | 101 | // The proxy backing the destination surface had better have been instantiated |
| 102 | // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget. |
| 103 | SkASSERT(lazyProxyData->fReplayDest->priv().peekSurface()); |
| 104 | return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->priv().peekSurface()); |
| 105 | }, |
| 106 | desc, |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 107 | fCharacterization.origin(), |
Robert Phillips | fde6fa0 | 2018-03-02 08:53:14 -0500 | [diff] [blame] | 108 | GrRenderTargetFlags::kNone, |
Robert Phillips | 83373a8 | 2018-02-14 07:35:32 -0500 | [diff] [blame] | 109 | GrProxyProvider::Textureable(fCharacterization.isTextureable()), |
| 110 | GrMipMapped::kNo, |
| 111 | SkBackingFit::kExact, |
| 112 | SkBudgeted::kYes); |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 113 | |
| 114 | sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext( |
| 115 | std::move(proxy), |
| 116 | fCharacterization.refColorSpace(), |
| 117 | &fCharacterization.surfaceProps()); |
| 118 | fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(), |
| 119 | sk_ref_sp(c->asRenderTargetContext())); |
Robert Phillips | e42edcc | 2017-12-13 11:50:22 -0500 | [diff] [blame] | 120 | return SkToBool(fSurface.get()); |
| 121 | } |
| 122 | |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 123 | SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 124 | if (!fContext) { |
| 125 | return nullptr; |
| 126 | } |
| 127 | |
| 128 | if (!fSurface && !this->init()) { |
| 129 | return nullptr; |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | return fSurface->getCanvas(); |
| 133 | } |
| 134 | |
| 135 | std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 136 | if (!fContext) { |
| 137 | return nullptr; |
| 138 | } |
| 139 | |
Robert Phillips | 6200036 | 2018-02-01 09:10:04 -0500 | [diff] [blame] | 140 | auto ddl = std::unique_ptr<SkDeferredDisplayList>( |
| 141 | new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData))); |
| 142 | |
| 143 | fContext->contextPriv().moveOpListsToDDL(ddl.get()); |
| 144 | return ddl; |
Robert Phillips | ad8a43f | 2017-08-30 12:06:35 -0400 | [diff] [blame] | 145 | } |
| 146 | |
Greg Daniel | a8d9211 | 2018-03-09 12:05:04 -0500 | [diff] [blame] | 147 | sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture( |
| 148 | const GrBackendFormat& backendFormat, |
| 149 | int width, |
| 150 | int height, |
| 151 | GrMipMapped mipMapped, |
| 152 | GrSurfaceOrigin origin, |
| 153 | SkColorType colorType, |
| 154 | SkAlphaType alphaType, |
| 155 | sk_sp<SkColorSpace> colorSpace, |
| 156 | TextureFulfillProc textureFulfillProc, |
| 157 | TextureReleaseProc textureReleaseProc, |
| 158 | TextureContext textureContext) { |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 159 | if (!fContext) { |
| 160 | return nullptr; |
| 161 | } |
| 162 | |
Greg Daniel | a8d9211 | 2018-03-09 12:05:04 -0500 | [diff] [blame] | 163 | return SkImage_Gpu::MakePromiseTexture(fContext.get(), |
| 164 | backendFormat, |
| 165 | width, |
| 166 | height, |
| 167 | mipMapped, |
| 168 | origin, |
| 169 | colorType, |
| 170 | alphaType, |
Kevin Lubick | b5502b2 | 2018-03-12 10:17:06 -0400 | [diff] [blame] | 171 | std::move(colorSpace), |
Greg Daniel | a8d9211 | 2018-03-09 12:05:04 -0500 | [diff] [blame] | 172 | textureFulfillProc, |
| 173 | textureReleaseProc, |
| 174 | textureContext); |
Greg Daniel | a8d9211 | 2018-03-09 12:05:04 -0500 | [diff] [blame] | 175 | } |
Robert Phillips | 6ceaafa | 2018-03-15 16:53:06 -0400 | [diff] [blame^] | 176 | |
| 177 | #endif |