aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-10-14 12:54:52 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-14 12:54:52 -0700
commit10528f1d5838ae1cac015024c4e8731484f888d1 (patch)
tree798e83363aee8208c90c929d307ca6403928a469 /src/gpu
parentfd2b067b9e6a8cc93581a61c67bb8ce3c626f60f (diff)
Store texture target on GrGLTexture. This is in preparation for using texture targets other than 2D.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLGpu.cpp161
-rw-r--r--src/gpu/gl/GrGLGpu.h13
-rw-r--r--src/gpu/gl/GrGLTexture.cpp1
-rw-r--r--src/gpu/gl/GrGLTexture.h4
4 files changed, 93 insertions, 86 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index cd6bf39adc..80f0171f57 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -426,7 +426,9 @@ GrTexture* GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
GrSurfaceDesc surfDesc;
idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
-
+ // We only support GL_TEXTURE_2D at the moment.
+ idDesc.fTarget = GR_GL_TEXTURE_2D;
+
switch (ownership) {
case kAdopt_GrWrapOwnership:
idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
@@ -457,7 +459,7 @@ GrTexture* GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
if (renderTarget) {
GrGLRenderTarget::IDDesc rtIDDesc;
if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_LifeCycle,
- idDesc.fTextureID, &rtIDDesc)) {
+ idDesc.fTextureID, idDesc.fTarget, &rtIDDesc)) {
return nullptr;
}
texture = new GrGLTextureRenderTarget(this, surfDesc, idDesc, rtIDDesc);
@@ -573,17 +575,17 @@ bool GrGLGpu::onWritePixels(GrSurface* surface,
}
this->setScratchTextureUnit();
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
+ GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
bool success = false;
if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
// We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixels()
SkASSERT(config == glTex->desc().fConfig);
- success = this->uploadCompressedTexData(glTex->desc(), buffer, false, left, top, width,
- height);
+ success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, false, left,
+ top, width, height);
} else {
- success = this->uploadTexData(glTex->desc(), false, left, top, width, height, config,
- buffer, rowBytes);
+ success = this->uploadTexData(glTex->desc(), glTex->target(), false, left, top, width,
+ height, config, buffer, rowBytes);
}
if (success) {
@@ -604,6 +606,7 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
}
bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
+ GrGLenum target,
bool isNewTexture,
int left, int top, int width, int height,
GrPixelConfig dataConfig,
@@ -719,13 +722,13 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
if (useTexStorage) {
// We never resize or change formats of textures.
GL_ALLOC_CALL(this->glInterface(),
- TexStorage2D(GR_GL_TEXTURE_2D,
+ TexStorage2D(target,
1, // levels
internalFormat,
desc.fWidth, desc.fHeight));
} else {
GL_ALLOC_CALL(this->glInterface(),
- TexImage2D(GR_GL_TEXTURE_2D,
+ TexImage2D(target,
0, // level
internalFormat,
desc.fWidth, desc.fHeight,
@@ -740,7 +743,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
// if we have data and we used TexStorage to create the texture, we
// now upload with TexSubImage.
if (data && useTexStorage) {
- GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
+ GL_CALL(TexSubImage2D(target,
0, // level
left, top,
width, height,
@@ -752,7 +755,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
if (swFlipY || glFlipY) {
top = desc.fHeight - (top + height);
}
- GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
+ GL_CALL(TexSubImage2D(target,
0, // level
left, top,
width, height,
@@ -775,6 +778,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
// the proper upload semantics. Then users can construct this function how they
// see fit if they want to go against the "standard" way to do it.
bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
+ GrGLenum target,
const void* data,
bool isNewTexture,
int left, int top, int width, int height) {
@@ -814,7 +818,7 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
if (isNewTexture) {
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
GL_ALLOC_CALL(this->glInterface(),
- CompressedTexImage2D(GR_GL_TEXTURE_2D,
+ CompressedTexImage2D(target,
0, // level
internalFormat,
width, height,
@@ -830,7 +834,7 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
return false;
}
- GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
+ GL_CALL(CompressedTexSubImage2D(target,
0, // level
left, top,
width, height,
@@ -884,6 +888,7 @@ static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
GrGLuint texID,
+ GrGLenum textureTarget,
GrGLRenderTarget::IDDesc* idDesc) {
idDesc->fMSColorRenderbufferID = 0;
idDesc->fRTFBOID = 0;
@@ -942,9 +947,9 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
fStats.incRenderTargetBinds();
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_COLOR_ATTACHMENT0,
- GR_GL_RENDERBUFFER,
- idDesc->fMSColorRenderbufferID));
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_RENDERBUFFER,
+ idDesc->fMSColorRenderbufferID));
if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) ||
!this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
@@ -960,12 +965,12 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) {
GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
+ textureTarget,
texID, 0, desc.fSampleCnt));
} else {
GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
+ textureTarget,
texID, 0));
}
if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) ||
@@ -1018,17 +1023,19 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GrGLTexture::IDDesc idDesc;
GL_CALL(GenTextures(1, &idDesc.fTextureID));
idDesc.fLifeCycle = lifeCycle;
+ // We only support GL_TEXTURE_2D at the moment.
+ idDesc.fTarget = GR_GL_TEXTURE_2D;
if (!idDesc.fTextureID) {
return return_null_texture();
}
this->setScratchTextureUnit();
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID));
+ GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID));
if (renderTarget && this->glCaps().textureUsageSupport()) {
// provides a hint about how this texture will be used
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_USAGE,
GR_GL_FRAMEBUFFER_ATTACHMENT));
}
@@ -1043,19 +1050,19 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
initialTexParams.fMagFilter = GR_GL_NEAREST;
initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_MAG_FILTER,
initialTexParams.fMagFilter));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_MIN_FILTER,
initialTexParams.fMinFilter));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_WRAP_S,
initialTexParams.fWrapS));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_WRAP_T,
initialTexParams.fWrapT));
- if (!this->uploadTexData(desc, true, 0, 0,
+ if (!this->uploadTexData(desc, idDesc.fTarget, true, 0, 0,
desc.fWidth, desc.fHeight,
desc.fConfig, srcData, rowBytes)) {
GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
@@ -1065,10 +1072,11 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GrGLTexture* tex;
if (renderTarget) {
// unbind the texture from the texture unit before binding it to the frame buffer
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
+ GL_CALL(BindTexture(idDesc.fTarget, 0));
GrGLRenderTarget::IDDesc rtIDDesc;
- if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) {
+ if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, idDesc.fTarget,
+ &rtIDDesc)) {
GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
return return_null_texture();
}
@@ -1095,13 +1103,15 @@ GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
GrGLTexture::IDDesc idDesc;
GL_CALL(GenTextures(1, &idDesc.fTextureID));
idDesc.fLifeCycle = lifeCycle;
+ // We only support GL_TEXTURE_2D at the moment.
+ idDesc.fTarget = GR_GL_TEXTURE_2D;
if (!idDesc.fTextureID) {
return return_null_texture();
}
this->setScratchTextureUnit();
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID));
+ GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID));
// Some drivers like to know filter/wrap before seeing glTexImage2D. Some
// drivers have a bug where an FBO won't be complete if it includes a
@@ -1113,20 +1123,20 @@ GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
initialTexParams.fMagFilter = GR_GL_NEAREST;
initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_MAG_FILTER,
initialTexParams.fMagFilter));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_MIN_FILTER,
initialTexParams.fMinFilter));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_WRAP_S,
initialTexParams.fWrapS));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+ GL_CALL(TexParameteri(idDesc.fTarget,
GR_GL_TEXTURE_WRAP_T,
initialTexParams.fWrapT));
- if (!this->uploadCompressedTexData(desc, srcData)) {
+ if (!this->uploadCompressedTexData(desc, idDesc.fTarget, srcData)) {
GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
return return_null_texture();
}
@@ -2293,9 +2303,10 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
}
uint32_t textureID = texture->getUniqueID();
+ GrGLenum target = texture->target();
if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
this->setTextureUnit(unitIdx);
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID()));
+ GL_CALL(BindTexture(target, texture->textureID()));
fHWBoundTextureUniqueIDs[unitIdx] = textureID;
}
@@ -2327,7 +2338,7 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
if (GrTextureParams::kMipMap_FilterMode == filterMode &&
texture->texturePriv().mipMapsAreDirty()) {
- GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D));
+ GL_CALL(GenerateMipmap(target));
texture->texturePriv().dirtyMipMaps(false);
}
@@ -2338,27 +2349,19 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
sizeof(newTexParams.fSwizzleRGBA));
if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
- GR_GL_TEXTURE_MAG_FILTER,
- newTexParams.fMagFilter));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter));
}
if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
- GR_GL_TEXTURE_MIN_FILTER,
- newTexParams.fMinFilter));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMinFilter));
}
if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
- GR_GL_TEXTURE_WRAP_S,
- newTexParams.fWrapS));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS));
}
if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
- GR_GL_TEXTURE_WRAP_T,
- newTexParams.fWrapT));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT));
}
if (this->glCaps().textureSwizzleSupport() &&
(setAll || memcmp(newTexParams.fSwizzleRGBA,
@@ -2368,14 +2371,14 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
if (this->glStandard() == kGLES_GrGLStandard) {
// ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
const GrGLenum* swizzle = newTexParams.fSwizzleRGBA;
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
- GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
} else {
GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGLint));
const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexParams.fSwizzleRGBA);
- GL_CALL(TexParameteriv(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
+ GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
}
}
texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
@@ -2681,12 +2684,13 @@ inline bool can_copy_texsubimage(const GrSurface* dst,
// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
// relative to is output.
-GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
- TempFBOTarget tempFBOTarget) {
+void GrGLGpu::bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
+ TempFBOTarget tempFBOTarget) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
if (nullptr == rt) {
SkASSERT(surface->asTexture());
GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
+ GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->target();
GrGLuint* tempFBOID;
tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTempDstFBOID;
@@ -2698,29 +2702,31 @@ GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID));
GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
+ target,
texID,
0));
viewport->fLeft = 0;
viewport->fBottom = 0;
viewport->fWidth = surface->width();
viewport->fHeight = surface->height();
- return *tempFBOID;
} else {
- GrGLuint tempFBOID = 0;
fStats.incRenderTargetBinds();
GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
*viewport = rt->getViewport();
- return tempFBOID;
}
}
-void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) {
- GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
- GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
- 0,
- 0));
+void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) {
+ // bindSurfaceFBOForCopy temporarily binds textures that are not render targets to
+ if (!surface->asRenderTarget()) {
+ SkASSERT(surface->asTexture());
+ GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())->target();
+ GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
+ GR_GL_COLOR_ATTACHMENT0,
+ textureTarget,
+ 0,
+ 0));
+ }
}
bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const {
@@ -2968,9 +2974,8 @@ void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
SkASSERT(can_copy_texsubimage(dst, src, this));
- GrGLuint srcFBO;
GrGLIRect srcVP;
- srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
+ this->bindSurfaceFBOForCopy(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
SkASSERT(dstTex);
// We modified the bound FBO
@@ -2984,20 +2989,18 @@ void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
src->origin());
this->setScratchTextureUnit();
- GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
+ GL_CALL(BindTexture(dstTex->target(), dstTex->textureID()));
GrGLint dstY;
if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
} else {
dstY = dstPoint.fY;
}
- GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0,
+ GL_CALL(CopyTexSubImage2D(dstTex->target(), 0,
dstPoint.fX, dstY,
srcGLRect.fLeft, srcGLRect.fBottom,
srcGLRect.fWidth, srcGLRect.fHeight));
- if (srcFBO) {
- this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER);
- }
+ this->unbindTextureFBOForCopy(GR_GL_FRAMEBUFFER, src);
}
bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
@@ -3013,14 +3016,10 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
}
}
- GrGLuint dstFBO;
- GrGLuint srcFBO;
GrGLIRect dstVP;
GrGLIRect srcVP;
- dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP,
- kDst_TempFBOTarget);
- srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP,
- kSrc_TempFBOTarget);
+ this->bindSurfaceFBOForCopy(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
+ this->bindSurfaceFBOForCopy(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
GrGLIRect srcGLRect;
@@ -3060,12 +3059,8 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
dstGLRect.fLeft + dstGLRect.fWidth,
dstGLRect.fBottom + dstGLRect.fHeight,
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
- if (dstFBO) {
- this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
- }
- if (srcFBO) {
- this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
- }
+ this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst);
+ this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src);
return true;
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index dee201292e..3fa498cce8 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -273,6 +273,7 @@ private:
GrGLenum* externalType) const;
// helper for onCreateTexture and writeTexturePixels
bool uploadTexData(const GrSurfaceDesc& desc,
+ GrGLenum target,
bool isNewTexture,
int left, int top, int width, int height,
GrPixelConfig dataConfig,
@@ -286,23 +287,29 @@ private:
// the texture is already in GPU memory and that it's going to be updated
// with new data.
bool uploadCompressedTexData(const GrSurfaceDesc& desc,
+ GrGLenum target,
const void* data,
bool isNewTexture = true,
int left = 0, int top = 0,
int width = -1, int height = -1);
bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
- GrGLuint texID, GrGLRenderTarget::IDDesc*);
+ GrGLenum textureTarget, GrGLuint texID,
+ GrGLRenderTarget::IDDesc*);
enum TempFBOTarget {
kSrc_TempFBOTarget,
kDst_TempFBOTarget
};
- GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
+ // Binds a surface as a FBO for a copy operation. If the surface already owns an FBO ID then
+ // that ID is bound. If not the surface is temporarily bound to a FBO and that FBO is bound.
+ // This must be paired with a call to unbindSurfaceFBOForCopy().
+ void bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
TempFBOTarget tempFBOTarget);
- void unbindTextureFromFBO(GrGLenum fboTarget);
+ // Must be called if bindSurfaceFBOForCopy was used to bind a surface for copying.
+ void unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface);
SkAutoTUnref<GrGLContext> fGLContext;
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 6f70d51a34..29f7423ba5 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -30,6 +30,7 @@ void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
SkASSERT(0 != idDesc.fTextureID);
fTexParams.invalidate();
fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
+ fTarget = idDesc.fTarget;
fTextureID = idDesc.fTextureID;
fTextureIDLifecycle = idDesc.fLifeCycle;
}
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index cffc64adc1..40a68eb9e9 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -28,6 +28,7 @@ public:
};
struct IDDesc {
+ GrGLenum fTarget;
GrGLuint fTextureID;
GrGpuResource::LifeCycle fLifeCycle;
};
@@ -52,6 +53,8 @@ public:
GrGLuint textureID() const { return fTextureID; }
+ GrGLenum target() const { return fTarget; }
+
protected:
// The public constructor registers this object with the cache. However, only the most derived
// class should register with the cache. This constructor does not do the registration and
@@ -69,6 +72,7 @@ protected:
private:
TexParams fTexParams;
GrGpu::ResetTimestamp fTexParamsTimestamp;
+ GrGLenum fTarget;
GrGLuint fTextureID;
// We track this separately from GrGpuResource because this may be both a texture and a render