Chromium Code Reviews| Index: src/gpu/gl/GrGLGpu.cpp |
| diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
| index bf0b297c8cf064620b4ac55586c9672ff969f75c..4d3cb09bd54672321f62785e204548c82c02a356 100644 |
| --- a/src/gpu/gl/GrGLGpu.cpp |
| +++ b/src/gpu/gl/GrGLGpu.cpp |
| @@ -649,8 +649,11 @@ bool GrGLGpu::onWritePixels(GrSurface* surface, |
| success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, |
| kWrite_UploadType, left, top, width, height); |
| } else { |
| - success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_UploadType, |
| - left, top, width, height, config, buffer, rowBytes); |
| + success = this->uploadTexData( |
| + glTex->desc(), |
| + reinterpret_cast<GrGLTextureInfo*>(glTex->getTextureHandle()), |
| + kWrite_UploadType, left, top, width, height, config, buffer, |
| + rowBytes); |
| } |
| if (success) { |
| @@ -687,8 +690,11 @@ bool GrGLGpu::onTransferPixels(GrSurface* surface, |
| GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); |
| bool success = false; |
| - success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_UploadType, |
| - left, top, width, height, config, buffer, rowBytes); |
| + success = this->uploadTexData( |
| + glTex->desc(), |
| + reinterpret_cast<GrGLTextureInfo*>(glTex->getTextureHandle()), |
| + kTransfer_UploadType, left, top, width, height, config, buffer, |
| + rowBytes); |
| if (success) { |
| glTex->texturePriv().dirtyMipMaps(true); |
| @@ -729,7 +735,7 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
| } |
| bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
| - GrGLenum target, |
| + GrGLTextureInfo* info, |
| UploadType uploadType, |
| int left, int top, int width, int height, |
| GrPixelConfig dataConfig, |
| @@ -826,20 +832,30 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
| !(0 == left && 0 == top && desc.fWidth == width && desc.fHeight == height)) { |
| succeeded = false; |
| } else { |
| - CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
| - GL_ALLOC_CALL(this->glInterface(), TexImage2D(target, 0, internalFormat, desc.fWidth, |
| - desc.fHeight, 0, externalFormat, |
| - externalType, dataOrOffset)); |
| - GrGLenum error = check_alloc_error(desc, this->glInterface()); |
| - if (error != GR_GL_NO_ERROR) { |
| - succeeded = false; |
| - } |
| + if (desc.fTextureStorageAllocator) { |
| + if (dataOrOffset) { |
| + GL_CALL(TexSubImage2D(info->fTarget, |
| + 0, // level |
| + left, top, |
| + width, height, |
| + externalFormat, externalType, dataOrOffset)); |
| + } |
| + } else { |
| + CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
| + GL_ALLOC_CALL(this->glInterface(), TexImage2D( |
| + info->fTarget, 0, internalFormat, desc.fWidth, desc.fHeight, 0, externalFormat, |
| + externalType, dataOrOffset)); |
| + GrGLenum error = check_alloc_error(desc, this->glInterface()); |
| + if (error != GR_GL_NO_ERROR) { |
| + succeeded = false; |
| + } |
| + } |
| } |
| } else { |
| if (swFlipY || glFlipY) { |
| top = desc.fHeight - (top + height); |
| } |
| - GL_CALL(TexSubImage2D(target, |
| + GL_CALL(TexSubImage2D(info->fTarget, |
| 0, // level |
| left, top, |
| width, height, |
| @@ -1102,52 +1118,10 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
| bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
| GrGLTexture::IDDesc idDesc; |
| - idDesc.fInfo.fID = 0; |
| - GL_CALL(GenTextures(1, &idDesc.fInfo.fID)); |
| idDesc.fLifeCycle = lifeCycle; |
| - // We only support GL_TEXTURE_2D at the moment. |
| - idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; |
| - |
| - if (!idDesc.fInfo.fID) { |
| - return return_null_texture(); |
| - } |
| - |
| - this->setScratchTextureUnit(); |
| - GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); |
| - |
| - if (renderTarget && this->glCaps().textureUsageSupport()) { |
| - // provides a hint about how this texture will be used |
| - GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| - GR_GL_TEXTURE_USAGE, |
| - GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| - } |
| - |
| - // 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 |
| - // texture that is not mipmap complete (considering the filter in use). |
| GrGLTexture::TexParams initialTexParams; |
| - // we only set a subset here so invalidate first |
| - initialTexParams.invalidate(); |
| - initialTexParams.fMinFilter = GR_GL_NEAREST; |
| - initialTexParams.fMagFilter = GR_GL_NEAREST; |
| - initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; |
| - initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; |
| - GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| - GR_GL_TEXTURE_MAG_FILTER, |
| - initialTexParams.fMagFilter)); |
| - GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| - GR_GL_TEXTURE_MIN_FILTER, |
| - initialTexParams.fMinFilter)); |
| - GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| - GR_GL_TEXTURE_WRAP_S, |
| - initialTexParams.fWrapS)); |
| - GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| - GR_GL_TEXTURE_WRAP_T, |
| - initialTexParams.fWrapT)); |
| - if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType, 0, 0, |
| - desc.fWidth, desc.fHeight, |
| - desc.fConfig, srcData, rowBytes)) { |
| - GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
| + if (!createTextureImpl(desc, &idDesc.fInfo, renderTarget, srcData, |
|
bsalomon
2016/01/26 22:20:54
nit, we prefix method calls with "this->"
erikchen
2016/01/27 21:55:15
Done.
|
| + &initialTexParams, rowBytes)) { |
| return return_null_texture(); |
| } |
| @@ -1370,6 +1344,75 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { |
| return this->glCaps().getStencilFormatIndexForConfig(config); |
| } |
| +bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, |
| + bool renderTarget, const void* srcData, |
| + GrGLTexture::TexParams* initialTexParams, size_t rowBytes) { |
| + // 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 |
| + // texture that is not mipmap complete (considering the filter in use). |
| + |
| + // we only set a subset here so invalidate first |
| + initialTexParams->invalidate(); |
| + initialTexParams->fMinFilter = GR_GL_NEAREST; |
| + initialTexParams->fMagFilter = GR_GL_NEAREST; |
| + initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE; |
| + initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE; |
| + |
| + if (desc.fTextureStorageAllocator) { |
| + if (!desc.fTextureStorageAllocator->allocateTextureStorage( |
| + reinterpret_cast<GrBackendObject>(info), desc.fWidth, desc.fHeight)) { |
| + return false; |
| + } |
| + |
| + if (!this->uploadTexData(desc, info, kNewTexture_UploadType, 0, 0, |
| + desc.fWidth, desc.fHeight, |
| + desc.fConfig, srcData, rowBytes)) { |
| + desc.fTextureStorageAllocator->deallocateTextureStorage( |
| + reinterpret_cast<GrBackendObject>(info)); |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + info->fID = 0; |
| + info->fTarget = GR_GL_TEXTURE_2D; |
| + GL_CALL(GenTextures(1, &(info->fID))); |
| + |
| + if (!info->fID) { |
| + return false; |
| + } |
| + |
| + this->setScratchTextureUnit(); |
| + GL_CALL(BindTexture(info->fTarget, info->fID)); |
| + |
| + if (renderTarget && this->glCaps().textureUsageSupport()) { |
| + // provides a hint about how this texture will be used |
| + GL_CALL(TexParameteri(info->fTarget, |
| + GR_GL_TEXTURE_USAGE, |
| + GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| + } |
| + |
| + GL_CALL(TexParameteri(info->fTarget, |
| + GR_GL_TEXTURE_MAG_FILTER, |
| + initialTexParams->fMagFilter)); |
| + GL_CALL(TexParameteri(info->fTarget, |
| + GR_GL_TEXTURE_MIN_FILTER, |
| + initialTexParams->fMinFilter)); |
| + GL_CALL(TexParameteri(info->fTarget, |
| + GR_GL_TEXTURE_WRAP_S, |
| + initialTexParams->fWrapS)); |
| + GL_CALL(TexParameteri(info->fTarget, |
| + GR_GL_TEXTURE_WRAP_T, |
| + initialTexParams->fWrapT)); |
| + if (!this->uploadTexData(desc, info, kNewTexture_UploadType, 0, 0, |
| + desc.fWidth, desc.fHeight, |
| + desc.fConfig, srcData, rowBytes)) { |
| + GL_CALL(DeleteTextures(1, &(info->fID))); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, |
| int width, |
| int height) { |