blob: 79e153116012409a0bcfff8797cdd1f15a7d19fa [file] [log] [blame]
Chris Dalton3d770272019-08-14 09:24:37 -06001/*
2 * Copyright 2019 Google LLC
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 "src/gpu/GrTextureResolveRenderTask.h"
9
10#include "src/gpu/GrGpu.h"
11#include "src/gpu/GrMemoryPool.h"
12#include "src/gpu/GrOpFlushState.h"
Chris Dalton4ece96d2019-08-30 11:26:39 -060013#include "src/gpu/GrRenderTarget.h"
Chris Dalton3d770272019-08-14 09:24:37 -060014#include "src/gpu/GrResourceAllocator.h"
15#include "src/gpu/GrTexturePriv.h"
16
Adlai Hollerd71b7b02020-06-08 15:55:00 -040017void GrTextureResolveRenderTask::disown(GrDrawingManager* drawingMgr) {
Chris Daltone2a903e2019-09-18 13:41:50 -060018 for (const auto& resolve : fResolves) {
Adlai Hollerd71b7b02020-06-08 15:55:00 -040019 drawingMgr->setLastRenderTask(resolve.fProxy.get(), nullptr);
Chris Daltone2a903e2019-09-18 13:41:50 -060020 }
Adlai Hollerd71b7b02020-06-08 15:55:00 -040021 GrRenderTask::disown(drawingMgr);
Chris Daltone2a903e2019-09-18 13:41:50 -060022}
23
Adlai Hollerd71b7b02020-06-08 15:55:00 -040024void GrTextureResolveRenderTask::addProxy(GrDrawingManager* drawingMgr,
25 sk_sp<GrSurfaceProxy> proxyRef,
26 GrSurfaceProxy::ResolveFlags flags,
27 const GrCaps& caps) {
Greg Daniel242536f2020-02-13 14:12:46 -050028 fResolves.emplace_back(std::move(proxyRef), flags);
29 GrSurfaceProxy* proxy = fResolves.back().fProxy.get();
Chris Dalton16a33c62019-09-24 22:19:17 -060030
Chris Daltone2a903e2019-09-18 13:41:50 -060031 // Ensure the last render task that operated on the proxy is closed. That's where msaa and
32 // mipmaps should have been marked dirty.
Adlai Hollerd71b7b02020-06-08 15:55:00 -040033 SkASSERT(!drawingMgr->getLastRenderTask(proxy)
34 || drawingMgr->getLastRenderTask(proxy)->isClosed());
Chris Daltone2a903e2019-09-18 13:41:50 -060035 SkASSERT(GrSurfaceProxy::ResolveFlags::kNone != flags);
36
37 if (GrSurfaceProxy::ResolveFlags::kMSAA & flags) {
38 GrRenderTargetProxy* renderTargetProxy = proxy->asRenderTargetProxy();
Chris Dalton4ece96d2019-08-30 11:26:39 -060039 SkASSERT(renderTargetProxy);
40 SkASSERT(renderTargetProxy->isMSAADirty());
Chris Dalton16a33c62019-09-24 22:19:17 -060041 fResolves.back().fMSAAResolveRect = renderTargetProxy->msaaDirtyRect();
Chris Dalton4ece96d2019-08-30 11:26:39 -060042 renderTargetProxy->markMSAAResolved();
43 }
44
Chris Daltone2a903e2019-09-18 13:41:50 -060045 if (GrSurfaceProxy::ResolveFlags::kMipMaps & flags) {
46 GrTextureProxy* textureProxy = proxy->asTextureProxy();
Chris Dalton4ece96d2019-08-30 11:26:39 -060047 SkASSERT(GrMipMapped::kYes == textureProxy->mipMapped());
48 SkASSERT(textureProxy->mipMapsAreDirty());
49 textureProxy->markMipMapsClean();
50 }
51
Chris Daltone2a903e2019-09-18 13:41:50 -060052 // Add the proxy as a dependency: We will read the existing contents of this texture while
Chris Dalton3d770272019-08-14 09:24:37 -060053 // generating mipmap levels and/or resolving MSAA.
Adlai Hollerd71b7b02020-06-08 15:55:00 -040054 this->addDependency(drawingMgr, proxy, GrMipMapped::kNo,
55 GrTextureResolveManager(nullptr), caps);
56 drawingMgr->setLastRenderTask(proxy, this);
Chris Dalton3d770272019-08-14 09:24:37 -060057}
58
59void GrTextureResolveRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
Chris Daltone2a903e2019-09-18 13:41:50 -060060 // This renderTask doesn't have "normal" ops, however we still need to add intervals so
61 // fEndOfOpsTaskOpIndices will remain in sync. We create fake op#'s to capture the fact that we
62 // manipulate the resolve proxies.
63 auto fakeOp = alloc->curOp();
64 for (const auto& resolve : fResolves) {
Greg Daniel242536f2020-02-13 14:12:46 -050065 alloc->addInterval(resolve.fProxy.get(), fakeOp, fakeOp,
Chris Daltone2a903e2019-09-18 13:41:50 -060066 GrResourceAllocator::ActualUse::kYes);
67 }
Chris Dalton3d770272019-08-14 09:24:37 -060068 alloc->incOps();
69}
70
71bool GrTextureResolveRenderTask::onExecute(GrOpFlushState* flushState) {
Chris Daltone2a903e2019-09-18 13:41:50 -060072 // Resolve all msaa back-to-back, before regenerating mipmaps.
73 for (const auto& resolve : fResolves) {
74 if (GrSurfaceProxy::ResolveFlags::kMSAA & resolve.fFlags) {
Greg Daniel242536f2020-02-13 14:12:46 -050075 GrSurfaceProxy* proxy = resolve.fProxy.get();
Chris Daltone2a903e2019-09-18 13:41:50 -060076 // peekRenderTarget might be null if there was an instantiation error.
Greg Daniel16f5c652019-10-29 11:26:01 -040077 if (GrRenderTarget* renderTarget = proxy->peekRenderTarget()) {
Chris Dalton798a31d2019-09-26 19:28:32 +000078 flushState->gpu()->resolveRenderTarget(renderTarget, resolve.fMSAAResolveRect,
Chris Dalton798a31d2019-09-26 19:28:32 +000079 GrGpu::ForExternalIO::kNo);
Chris Dalton798a31d2019-09-26 19:28:32 +000080 }
Chris Dalton4ece96d2019-08-30 11:26:39 -060081 }
82 }
Chris Daltone2a903e2019-09-18 13:41:50 -060083 // Regenerate all mipmaps back-to-back.
84 for (const auto& resolve : fResolves) {
85 if (GrSurfaceProxy::ResolveFlags::kMipMaps & resolve.fFlags) {
86 // peekTexture might be null if there was an instantiation error.
Greg Daniel242536f2020-02-13 14:12:46 -050087 GrTexture* texture = resolve.fProxy->peekTexture();
Chris Daltone2a903e2019-09-18 13:41:50 -060088 if (texture && texture->texturePriv().mipMapsAreDirty()) {
89 flushState->gpu()->regenerateMipMapLevels(texture);
Chris Dalton16a33c62019-09-24 22:19:17 -060090 SkASSERT(!texture->texturePriv().mipMapsAreDirty());
Chris Daltone2a903e2019-09-18 13:41:50 -060091 }
Chris Dalton4ece96d2019-08-30 11:26:39 -060092 }
Chris Dalton3d770272019-08-14 09:24:37 -060093 }
94
95 return true;
96}
Chris Daltone2a903e2019-09-18 13:41:50 -060097
98#ifdef SK_DEBUG
Michael Ludwigfcdd0612019-11-25 08:34:31 -050099void GrTextureResolveRenderTask::visitProxies_debugOnly(const GrOp::VisitProxyFunc& fn) const {
Chris Daltone2a903e2019-09-18 13:41:50 -0600100 for (const auto& resolve : fResolves) {
Greg Daniel242536f2020-02-13 14:12:46 -0500101 fn(resolve.fProxy.get(), GrMipMapped::kNo);
Chris Daltone2a903e2019-09-18 13:41:50 -0600102 }
103}
104#endif