1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDeferredDisplayListRecorder.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrProxyProvider.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGpuDevice.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface_Gpu.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h" // TODO: remove 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDeferredDisplayList.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurfaceCharacterization.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder( 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSurfaceCharacterization& characterization) 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fCharacterization(characterization) { 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() { 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU && !defined(SK_RASTER_RECORDER_IMPLEMENTATION) 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxyProvider = fContext->contextPriv().proxyProvider(); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // DDL TODO: Remove this. DDL contexts should allow for deletion while still having live 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // uniquely keyed proxies. 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot proxyProvider->removeAllUniqueKeys(); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkDeferredDisplayListRecorder::init() { 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fSurface); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_RASTER_RECORDER_IMPLEMENTATION 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Use raster right now to allow threading 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkImageInfo ii = SkImageInfo::Make(fCharacterization.width(), fCharacterization.height(), 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kN32_SkColorType, kOpaque_SkAlphaType, 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCharacterization.refColorSpace()); 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSurface = SkSurface::MakeRaster(ii, &fCharacterization.surfaceProps()); 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkToBool(fSurface.get()); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fLazyProxyData); 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fContext) { 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fContext = GrContextPriv::MakeDDL(fCharacterization.contextInfo()); 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fContext) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>( 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new SkDeferredDisplayList::LazyProxyData); 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto proxyProvider = fContext->contextPriv().proxyProvider(); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrSurfaceDesc desc; 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fFlags = kRenderTarget_GrSurfaceFlag; 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fOrigin = fCharacterization.origin(); 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fWidth = fCharacterization.width(); 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fHeight = fCharacterization.height(); 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fConfig = fCharacterization.config(); 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot desc.fSampleCnt = fCharacterization.stencilCount(); 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData; 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // proxy, when instantiated, will use the GrTexture that backs the SkSurface that the 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // DDL is being replayed into. 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrSurfaceProxy> proxy = proxyProvider->createLazyProxy( 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot [ lazyProxyData ] (GrResourceProvider* resourceProvider, GrSurfaceOrigin* /* outOrigin */) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!resourceProvider) { 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_sp<GrTexture>(); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The proxy backing the destination surface had better have been instantiated 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // prior to the proxy backing the DLL's surface. Steal its GrTexture. 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // DDL TODO: What do we do in the case where the Surface we're replaying into 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // isn't texturable? 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(lazyProxyData->fReplayDest->priv().peekTexture()); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return sk_ref_sp<GrTexture>(lazyProxyData->fReplayDest->priv().peekTexture()); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes); 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext( 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::move(proxy), 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCharacterization.refColorSpace(), 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fCharacterization.surfaceProps()); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(), 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_ref_sp(c->asRenderTargetContext())); 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkToBool(fSurface.get()); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkCanvas* SkDeferredDisplayListRecorder::getCanvas() { 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fSurface) { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->init()) { 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fSurface->getCanvas(); 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_RASTER_RECORDER_IMPLEMENTATION 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkImage> img = fSurface->makeImageSnapshot(); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSurface.reset(); 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO: need to wrap the opLists associated with the deferred draws 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // in the SkDeferredDisplayList. 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return std::unique_ptr<SkDeferredDisplayList>( 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new SkDeferredDisplayList(fCharacterization, std::move(img))); 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto ddl = std::unique_ptr<SkDeferredDisplayList>( 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData))); 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fContext->contextPriv().moveOpListsToDDL(ddl.get()); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return ddl; 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif // SK_RASTER_RECORDER_IMPLEMENTATION 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 145