@@ -207,45 +207,75 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
207207 }
208208
209209 if (readFlag == GrCaps::SurfaceReadPixelsSupport::kCopyToTexture2D || canvas2DFastPath) {
210- GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
211- ? GrColorType::kRGBA_8888 : this ->colorInfo ().colorType ();
212- sk_sp<SkColorSpace> cs = canvas2DFastPath ? nullptr : this ->colorInfo ().refColorSpace ();
213-
214- auto tempCtx = GrRenderTargetContext::Make (
215- dContext, colorType, std::move (cs), SkBackingFit::kApprox , dstInfo.dimensions (),
216- 1 , GrMipmapped::kNo , GrProtected::kNo , kTopLeft_GrSurfaceOrigin );
217- if (!tempCtx) {
218- return false ;
219- }
210+ std::unique_ptr<GrSurfaceContext> tempCtx;
211+ if (this ->asTextureProxy ()) {
212+ GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
213+ ? GrColorType::kRGBA_8888
214+ : this ->colorInfo ().colorType ();
215+ sk_sp<SkColorSpace> cs = canvas2DFastPath ? nullptr : this ->colorInfo ().refColorSpace ();
216+
217+ tempCtx = GrRenderTargetContext::Make (
218+ dContext, colorType, std::move (cs), SkBackingFit::kApprox , dstInfo.dimensions (),
219+ 1 , GrMipMapped::kNo , GrProtected::kNo , kTopLeft_GrSurfaceOrigin );
220+ if (!tempCtx) {
221+ return false ;
222+ }
220223
221- std::unique_ptr<GrFragmentProcessor> fp;
222- if (canvas2DFastPath) {
223- fp = dContext->priv ().createPMToUPMEffect (
224- GrTextureEffect::Make (this ->readSurfaceView (), this ->colorInfo ().alphaType ()));
225- if (dstInfo.colorType () == GrColorType::kBGRA_8888 ) {
226- fp = GrFragmentProcessor::SwizzleOutput (std::move (fp), GrSwizzle::BGRA ());
227- dstInfo = dstInfo.makeColorType (GrColorType::kRGBA_8888 );
224+ std::unique_ptr<GrFragmentProcessor> fp;
225+ if (canvas2DFastPath) {
226+ fp = dContext->priv ().createPMToUPMEffect (GrTextureEffect::Make (
227+ this ->readSurfaceView (), this ->colorInfo ().alphaType ()));
228+ if (dstInfo.colorType () == GrColorType::kBGRA_8888 ) {
229+ fp = GrFragmentProcessor::SwizzleOutput (std::move (fp), GrSwizzle::BGRA ());
230+ dstInfo = dstInfo.makeColorType (GrColorType::kRGBA_8888 );
231+ }
232+ // The render target context is incorrectly tagged as kPremul even though we're
233+ // writing unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type
234+ // so we don't double unpremul.
235+ dstInfo = dstInfo.makeAlphaType (kPremul_SkAlphaType );
236+ } else {
237+ fp = GrTextureEffect::Make (this ->readSurfaceView (), this ->colorInfo ().alphaType ());
238+ }
239+ if (!fp) {
240+ return false ;
228241 }
229- // The render target context is incorrectly tagged as kPremul even though we're writing
230- // unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type so we don't
231- // double unpremul.
232- dstInfo = dstInfo.makeAlphaType (kPremul_SkAlphaType );
242+ GrPaint paint;
243+ paint.setPorterDuffXPFactory (SkBlendMode::kSrc );
244+ paint.setColorFragmentProcessor (std::move (fp));
245+
246+ tempCtx->asRenderTargetContext ()->fillRectToRect (
247+ nullptr , std::move (paint), GrAA::kNo , SkMatrix::I (),
248+ SkRect::MakeWH (dstInfo.width (), dstInfo.height ()),
249+ SkRect::MakeXYWH (pt.fX , pt.fY , dstInfo.width (), dstInfo.height ()));
250+ pt = {0 , 0 };
233251 } else {
234- fp = GrTextureEffect::Make (this ->readSurfaceView (), this ->colorInfo ().alphaType ());
235- }
236- if (!fp) {
237- return false ;
252+ auto restrictions = this ->caps ()->getDstCopyRestrictions (this ->asRenderTargetProxy (),
253+ this ->colorInfo ().colorType ());
254+ sk_sp<GrSurfaceProxy> copy;
255+ static constexpr auto kFit = SkBackingFit::kExact ;
256+ static constexpr auto kBudgeted = SkBudgeted::kYes ;
257+ static constexpr auto kMipMapped = GrMipMapped::kNo ;
258+ if (restrictions.fMustCopyWholeSrc ) {
259+ copy = GrSurfaceProxy::Copy (fContext , srcProxy, this ->origin (), kMipMapped , kFit ,
260+ kBudgeted );
261+ } else {
262+ auto srcRect = SkIRect::MakeXYWH (pt.fX , pt.fY , dstInfo.width (), dstInfo.height ());
263+ copy = GrSurfaceProxy::Copy (fContext , srcProxy, this ->origin (), kMipMapped , srcRect,
264+ kFit , kBudgeted , restrictions.fRectsMustMatch );
265+ pt = {0 , 0 };
266+ }
267+ if (!copy) {
268+ return false ;
269+ }
270+ GrSurfaceProxyView view{std::move (copy), this ->origin (), this ->readSwizzle ()};
271+ tempCtx = GrSurfaceContext::Make (dContext,
272+ std::move (view),
273+ this ->colorInfo ().colorType (),
274+ this ->colorInfo ().alphaType (),
275+ this ->colorInfo ().refColorSpace ());
276+ SkASSERT (tempCtx);
238277 }
239- GrPaint paint;
240- paint.setPorterDuffXPFactory (SkBlendMode::kSrc );
241- paint.setColorFragmentProcessor (std::move (fp));
242-
243- tempCtx->asRenderTargetContext ()->fillRectToRect (
244- nullptr , std::move (paint), GrAA::kNo , SkMatrix::I (),
245- SkRect::MakeWH (dstInfo.width (), dstInfo.height ()),
246- SkRect::MakeXYWH (pt.fX , pt.fY , dstInfo.width (), dstInfo.height ()));
247-
248- return tempCtx->readPixels (dContext, dstInfo, dst, rowBytes, {0 , 0 });
278+ return tempCtx->readPixels (dContext, dstInfo, dst, rowBytes, pt);
249279 }
250280
251281 bool flip = this ->origin () == kBottomLeft_GrSurfaceOrigin ;
0 commit comments