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(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(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(surface->asRenderTarget()); if (nullptr == rt) { SkASSERT(surface->asTexture()); GrGLuint texID = static_cast(surface->asTexture())->textureID(); + GrGLenum target = static_cast(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(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(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 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