• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 "GrTextureContext.h"
9 #include "GrDrawingManager.h"
10 #include "GrResourceProvider.h"
11 #include "GrTextureOpList.h"
12 
13 #include "../private/GrAuditTrail.h"
14 
15 #define ASSERT_SINGLE_OWNER \
16     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
17 #define RETURN_FALSE_IF_ABANDONED  if (this->drawingManager()->wasAbandoned()) { return false; }
18 
GrTextureContext(GrContext * context,GrDrawingManager * drawingMgr,sk_sp<GrTextureProxy> textureProxy,sk_sp<SkColorSpace> colorSpace,GrAuditTrail * auditTrail,GrSingleOwner * singleOwner)19 GrTextureContext::GrTextureContext(GrContext* context,
20                                    GrDrawingManager* drawingMgr,
21                                    sk_sp<GrTextureProxy> textureProxy,
22                                    sk_sp<SkColorSpace> colorSpace,
23                                    GrAuditTrail* auditTrail,
24                                    GrSingleOwner* singleOwner)
25     : GrSurfaceContext(context, drawingMgr, std::move(colorSpace), auditTrail, singleOwner)
26     , fTextureProxy(std::move(textureProxy))
27     , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) {
28     SkDEBUGCODE(this->validate();)
29 }
30 
31 #ifdef SK_DEBUG
validate() const32 void GrTextureContext::validate() const {
33     SkASSERT(fTextureProxy);
34     fTextureProxy->validate(fContext);
35 
36     if (fOpList && !fOpList->isClosed()) {
37         SkASSERT(fTextureProxy->getLastOpList() == fOpList);
38     }
39 }
40 #endif
41 
~GrTextureContext()42 GrTextureContext::~GrTextureContext() {
43     ASSERT_SINGLE_OWNER
44     SkSafeUnref(fOpList);
45 }
46 
asRenderTargetProxy()47 GrRenderTargetProxy* GrTextureContext::asRenderTargetProxy() {
48     // If the proxy can return an RTProxy it should've been wrapped in a RTContext
49     SkASSERT(!fTextureProxy->asRenderTargetProxy());
50     return nullptr;
51 }
52 
asRenderTargetProxyRef()53 sk_sp<GrRenderTargetProxy> GrTextureContext::asRenderTargetProxyRef() {
54     // If the proxy can return an RTProxy it should've been wrapped in a RTContext
55     SkASSERT(!fTextureProxy->asRenderTargetProxy());
56     return nullptr;
57 }
58 
getOpList()59 GrTextureOpList* GrTextureContext::getOpList() {
60     ASSERT_SINGLE_OWNER
61     SkDEBUGCODE(this->validate();)
62 
63     if (!fOpList || fOpList->isClosed()) {
64         fOpList = this->drawingManager()->newOpList(fTextureProxy.get());
65     }
66 
67     return fOpList;
68 }
69 
70 // TODO: move this (and GrRenderTargetContext::copy) to GrSurfaceContext?
onCopy(GrSurfaceProxy * srcProxy,const SkIRect & srcRect,const SkIPoint & dstPoint)71 bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
72                               const SkIRect& srcRect,
73                               const SkIPoint& dstPoint) {
74     ASSERT_SINGLE_OWNER
75     RETURN_FALSE_IF_ABANDONED
76     SkDEBUGCODE(this->validate();)
77     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copy");
78 
79     // TODO: defer instantiation until flush time
80     sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider())));
81     if (!src) {
82         return false;
83     }
84 
85 #ifndef ENABLE_MDB
86     // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
87     // execute the copy immediately. Ensure the data is ready.
88     src->flushWrites();
89 #endif
90 
91     // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
92     sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider())));
93     if (!tex) {
94         return false;
95     }
96 
97     GrTextureOpList* opList = this->getOpList();
98     bool result = opList->copySurface(tex.get(), src.get(), srcRect, dstPoint);
99 
100 #ifndef ENABLE_MDB
101     GrOpFlushState flushState(fContext->getGpu(), nullptr);
102     opList->prepareOps(&flushState);
103     opList->executeOps(&flushState);
104     opList->reset();
105 #endif
106 
107     return result;
108 }
109 
110 // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
onReadPixels(const SkImageInfo & dstInfo,void * dstBuffer,size_t dstRowBytes,int x,int y,uint32_t flags)111 bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
112                                     size_t dstRowBytes, int x, int y, uint32_t flags) {
113     // TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
114     GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
115     if (kUnknown_GrPixelConfig == config) {
116         return false;
117     }
118 
119     // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels
120     if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
121         flags |= GrContext::kUnpremul_PixelOpsFlag;
122     }
123 
124     // Deferral of the VRAM resources must end in this instance anyway
125     sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider())));
126     if (!tex) {
127         return false;
128     }
129 
130     return tex->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
131                            config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
132 }
133 
134 // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
onWritePixels(const SkImageInfo & srcInfo,const void * srcBuffer,size_t srcRowBytes,int x,int y,uint32_t flags)135 bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
136                                      size_t srcRowBytes, int x, int y,
137                                      uint32_t flags) {
138     // TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
139     GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
140     if (kUnknown_GrPixelConfig == config) {
141         return false;
142     }
143     if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
144         flags |= GrContext::kUnpremul_PixelOpsFlag;
145     }
146 
147     // Deferral of the VRAM resources must end in this instance anyway
148     sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider())));
149     if (!tex) {
150         return false;
151     }
152 
153     return tex->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
154                             config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
155 }
156