blob: aef1828d309288af8d7bc71cf610d08a299059cb [file] [log] [blame]
bsalomon872062c2015-08-18 12:12:35 -07001/*
2 * Copyright 2015 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/ops/GrCopySurfaceOp.h"
Robert Phillips7c525e62018-06-12 10:11:12 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/private/GrRecordingContext.h"
11#include "src/gpu/GrGpu.h"
12#include "src/gpu/GrMemoryPool.h"
13#include "src/gpu/GrRecordingContextPriv.h"
Greg Daniel46cfbc62019-06-07 11:43:30 -040014#include "src/gpu/geometry/GrRect.h"
bsalomon872062c2015-08-18 12:12:35 -070015
Robert Phillipsb97da532019-02-12 15:24:12 -050016std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrRecordingContext* context,
Robert Phillips7c525e62018-06-12 10:11:12 -040017 GrSurfaceProxy* dstProxy,
18 GrSurfaceProxy* srcProxy,
Robert Phillipsbf25d432017-04-07 10:08:53 -040019 const SkIRect& srcRect,
Brian Salomonf8334782017-01-03 09:42:58 -050020 const SkIPoint& dstPoint) {
Robert Phillipsbf25d432017-04-07 10:08:53 -040021 SkASSERT(dstProxy);
22 SkASSERT(srcProxy);
bsalomon872062c2015-08-18 12:12:35 -070023 SkIRect clippedSrcRect;
24 SkIPoint clippedDstPoint;
Robert Phillipsbf25d432017-04-07 10:08:53 -040025 // If the rect is outside the srcProxy or dstProxy then we've already succeeded.
Greg Daniel46cfbc62019-06-07 11:43:30 -040026 if (!GrClipSrcRectAndDstPoint(dstProxy->isize(), srcProxy->isize(), srcRect, dstPoint,
27 &clippedSrcRect, &clippedDstPoint)) {
halcanary96fcdcc2015-08-27 07:41:13 -070028 return nullptr;
bsalomon872062c2015-08-18 12:12:35 -070029 }
Jim Van Verth1676cb92019-01-15 13:24:45 -050030 if (GrPixelConfigIsCompressed(dstProxy->config())) {
31 return nullptr;
32 }
Robert Phillipsbf25d432017-04-07 10:08:53 -040033
Robert Phillips9da87e02019-02-04 13:26:26 -050034 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040035
Greg Daniela47ab492019-06-11 16:44:23 -040036 return pool->allocate<GrCopySurfaceOp>(srcProxy, dstProxy, clippedSrcRect, clippedDstPoint);
bsalomon872062c2015-08-18 12:12:35 -070037}
Robert Phillips646e4292017-06-13 12:44:56 -040038
Brian Salomon588cec72018-11-14 13:56:37 -050039void GrCopySurfaceOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
Robert Phillips12c46292019-04-23 07:36:17 -040040 SkASSERT(fSrc.get()->isInstantiated());
Robert Phillips646e4292017-06-13 12:44:56 -040041
Greg Daniel46cfbc62019-06-07 11:43:30 -040042 // If we are using approx surfaces we may need to adjust our srcRect or dstPoint if the origin
43 // is bottom left.
44 GrSurfaceProxy* src = fSrc.get();
45 if (src->origin() == kBottomLeft_GrSurfaceOrigin) {
46 GrSurfaceProxy* dst = fDst.get();
47 SkASSERT(dst->isInstantiated());
48 if (src->height() != src->peekSurface()->height()) {
49 fSrcRect.offset(0, src->peekSurface()->height() - src->height());
50 }
51 if (dst->height() != dst->peekSurface()->height()) {
52 fDstPoint.fY = fDstPoint.fY + (dst->peekSurface()->height() - dst->height());
53 }
54 }
55
56 state->commandBuffer()->copy(fSrc.get()->peekSurface(), fSrcRect, fDstPoint);
Robert Phillips646e4292017-06-13 12:44:56 -040057}