aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLGpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl/GrGLGpu.cpp')
-rw-r--r--src/gpu/gl/GrGLGpu.cpp141
1 files changed, 40 insertions, 101 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index ba85868ddd..908d367fcd 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3293,70 +3293,27 @@ static inline bool can_blit_framebuffer_for_copy_surface(
const GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,
const SkIPoint& dstPoint,
- const GrGLGpu* gpu) {
- auto blitFramebufferFlags = gpu->glCaps().blitFramebufferSupportFlags();
- if (!gpu->glCaps().canConfigBeFBOColorAttachment(dst->config()) ||
- !gpu->glCaps().canConfigBeFBOColorAttachment(src->config())) {
- return false;
+ const GrGLCaps& caps) {
+ int dstSampleCnt = 0;
+ int srcSampleCnt = 0;
+ if (const GrRenderTarget* rt = dst->asRenderTarget()) {
+ dstSampleCnt = rt->numColorSamples();
+ }
+ if (const GrRenderTarget* rt = src->asRenderTarget()) {
+ srcSampleCnt = rt->numColorSamples();
}
- // Blits are not allowed between int color buffers and float/fixed color buffers. GrGpu should
- // have filtered such cases out.
+ SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTarget()));
+ SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTarget()));
+
const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
- const GrRenderTarget* dstRT = dst->asRenderTarget();
- const GrRenderTarget* srcRT = src->asRenderTarget();
- if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) {
- return false;
- }
- if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) {
- return false;
- }
- if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
- return false;
- }
- if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
- // We would mirror to compensate for origin changes. Note that copySurface is
- // specified such that the src and dst rects are the same.
- if (dstOrigin != srcOrigin) {
- return false;
- }
- }
- if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
- if (srcRT && srcRT->numColorSamples() > 1) {
- if (dstRT && 1 == dstRT->numColorSamples()) {
- return false;
- }
- if (SkRect::Make(srcRect) != srcRT->getBoundsRect()) {
- return false;
- }
- }
- }
- if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
- if (dstRT && dstRT->numColorSamples() > 1) {
- return false;
- }
- }
- if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
- if (dst->config() != src->config()) {
- return false;
- }
- } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
- const GrRenderTarget* srcRT = src->asRenderTarget();
- if (srcRT && srcRT->numColorSamples() > 1 && dst->config() != src->config()) {
- return false;
- }
- }
- if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
- if (srcRT && srcRT->numColorSamples() > 1) {
- if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
- return false;
- }
- if (dstOrigin != srcOrigin) {
- return false;
- }
- }
- }
- return true;
+
+ bool dstIsGLTexture2D = dstTex ? GR_GL_TEXTURE_2D == dstTex->target() : false;
+ bool srcIsGLTexture2D = srcTex ? GR_GL_TEXTURE_2D == srcTex->target() : false;
+
+ return caps.canCopyAsBlit(dst->config(), dstSampleCnt, SkToBool(dstTex), dstIsGLTexture2D,
+ dstOrigin, src->config(), srcSampleCnt, SkToBool(srcTex),
+ srcIsGLTexture2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint);
}
static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps& glCaps) {
@@ -3369,45 +3326,23 @@ static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps
static inline bool can_copy_texsubimage(const GrSurface* dst, GrSurfaceOrigin dstOrigin,
const GrSurface* src, GrSurfaceOrigin srcOrigin,
- const GrGLGpu* gpu) {
- // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
- // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
- // many drivers would allow it to work, but ANGLE does not.
- if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() &&
- (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) {
- return false;
- }
+ const GrGLCaps& caps) {
+
const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
- // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer)
- // then we don't want to copy to the texture but to the MSAA buffer.
- if (dstRT && rt_has_msaa_render_buffer(dstRT, gpu->glCaps())) {
- return false;
- }
const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
- // If the src is multisampled (and uses an extension where there is a separate MSAA
- // renderbuffer) then it is an invalid operation to call CopyTexSubImage
- if (srcRT && rt_has_msaa_render_buffer(srcRT, gpu->glCaps())) {
- return false;
- }
-
const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
- // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
- // texture.
- if (!dstTex) {
- return false;
- }
-
const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
- // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
- // is required.
- if (gpu->glCaps().canConfigBeFBOColorAttachment(src->config()) &&
- (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) && dstTex->target() == GR_GL_TEXTURE_2D &&
- dstOrigin == srcOrigin) {
- return true;
- } else {
- return false;
- }
+ bool dstHasMSAARenderBuffer = dstRT ? rt_has_msaa_render_buffer(dstRT, caps) : false;
+ bool srcHasMSAARenderBuffer = srcRT ? rt_has_msaa_render_buffer(srcRT, caps) : false;
+
+ bool dstIsGLTexture2D = dstTex ? GR_GL_TEXTURE_2D == dstTex->target() : false;
+ bool srcIsGLTexture2D = srcTex ? GR_GL_TEXTURE_2D == srcTex->target() : false;
+
+ return caps.canCopyTexSubImage(dst->config(), dstHasMSAARenderBuffer, SkToBool(dstTex),
+ dstIsGLTexture2D, dstOrigin, src->config(),
+ srcHasMSAARenderBuffer, SkToBool(srcTex), srcIsGLTexture2D,
+ srcOrigin);
}
// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
@@ -3472,24 +3407,24 @@ bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
// Don't prefer copying as a draw if the dst doesn't already have a FBO object.
// This implicitly handles this->glCaps().useDrawInsteadOfAllRenderTargetWrites().
bool preferCopy = SkToBool(dst->asRenderTarget());
- if (preferCopy && src->asTexture()) {
+ if (preferCopy && this->glCaps().canCopyAsDraw(dst->config(), SkToBool(src->asTexture()))) {
if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) {
return true;
}
}
- if (can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this)) {
+ if (can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this->glCaps())) {
this->copySurfaceAsCopyTexSubImage(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
return true;
}
if (can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint, this)) {
+ srcRect, dstPoint, this->glCaps())) {
return this->copySurfaceAsBlitFramebuffer(dst, dstOrigin, src, srcOrigin,
srcRect, dstPoint);
}
- if (!preferCopy && src->asTexture()) {
+ if (!preferCopy && this->glCaps().canCopyAsDraw(dst->config(), SkToBool(src->asTexture()))) {
if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) {
return true;
}
@@ -4012,6 +3947,10 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
int progIdx = TextureToCopyProgramIdx(srcTex);
+ if (!this->glCaps().canConfigBeFBOColorAttachment(dst->config())) {
+ return false;
+ }
+
if (!fCopyPrograms[progIdx].fProgram) {
if (!this->createCopyProgram(srcTex)) {
SkDebugf("Failed to create copy program.\n");
@@ -4097,7 +4036,7 @@ void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOr
GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
- SkASSERT(can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this));
+ SkASSERT(can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this->glCaps()));
GrGLIRect srcVP;
this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
@@ -4130,7 +4069,7 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOr
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
SkASSERT(can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint, this));
+ srcRect, dstPoint, this->glCaps()));
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
if (dst == src) {