blob: 0dfcc292a5977faa16944cd38cf6f6b18070618d [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
Greg Daniel46cfbc62019-06-07 11:43:30 -040034 SkASSERT(dstProxy->origin() == srcProxy->origin());
35 SkIRect adjSrcRect;
36 adjSrcRect.fLeft = clippedSrcRect.fLeft;
37 adjSrcRect.fRight = clippedSrcRect.fRight;
38 SkIPoint adjDstPoint;
39 adjDstPoint.fX = clippedDstPoint.fX;
40
41 // If it is bottom left origin we must flip the rects.
42 SkASSERT(dstProxy->origin() == srcProxy->origin());
43 if (kBottomLeft_GrSurfaceOrigin == srcProxy->origin()) {
44 adjSrcRect.fTop = srcProxy->height() - clippedSrcRect.fBottom;
45 adjSrcRect.fBottom = srcProxy->height() - clippedSrcRect.fTop;
46 adjDstPoint.fY = dstProxy->height() - clippedDstPoint.fY - clippedSrcRect.height();
47 } else {
48 adjSrcRect.fTop = clippedSrcRect.fTop;
49 adjSrcRect.fBottom = clippedSrcRect.fBottom;
50 adjDstPoint.fY = clippedDstPoint.fY;
51 }
52
Robert Phillips9da87e02019-02-04 13:26:26 -050053 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040054
Greg Daniel46cfbc62019-06-07 11:43:30 -040055 return pool->allocate<GrCopySurfaceOp>(srcProxy, dstProxy, adjSrcRect, adjDstPoint);
bsalomon872062c2015-08-18 12:12:35 -070056}
Robert Phillips646e4292017-06-13 12:44:56 -040057
Brian Salomon588cec72018-11-14 13:56:37 -050058void GrCopySurfaceOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
Robert Phillips12c46292019-04-23 07:36:17 -040059 SkASSERT(fSrc.get()->isInstantiated());
Robert Phillips646e4292017-06-13 12:44:56 -040060
Greg Daniel46cfbc62019-06-07 11:43:30 -040061 // If we are using approx surfaces we may need to adjust our srcRect or dstPoint if the origin
62 // is bottom left.
63 GrSurfaceProxy* src = fSrc.get();
64 if (src->origin() == kBottomLeft_GrSurfaceOrigin) {
65 GrSurfaceProxy* dst = fDst.get();
66 SkASSERT(dst->isInstantiated());
67 if (src->height() != src->peekSurface()->height()) {
68 fSrcRect.offset(0, src->peekSurface()->height() - src->height());
69 }
70 if (dst->height() != dst->peekSurface()->height()) {
71 fDstPoint.fY = fDstPoint.fY + (dst->peekSurface()->height() - dst->height());
72 }
73 }
74
75 state->commandBuffer()->copy(fSrc.get()->peekSurface(), fSrcRect, fDstPoint);
Robert Phillips646e4292017-06-13 12:44:56 -040076}