Store texture target on GrGLTexture. This is in preparation for using texture targets other than 2D.
Review URL: https://codereview.chromium.org/1403123002
This commit is contained in:
parent
fd2b067b9e
commit
10528f1d58
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user