Index: src/gpu/gl/GrGpuGL.cpp |
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp |
index 7275f6f73b12a059164a92abab9189de451570e5..7568ba32cf195099ce54d005d2567fece1b1462d 100644 |
--- a/src/gpu/gl/GrGpuGL.cpp |
+++ b/src/gpu/gl/GrGpuGL.cpp |
@@ -702,6 +702,41 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc, |
return succeeded; |
} |
+bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc, |
+ const void* data) { |
+ SkASSERT(NULL != data); |
+ |
robertphillips
2014/05/30 15:00:22
Can we test this case?
|
+ // No support for software flip y, yet... |
+ SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
+ |
+ // Make sure that the width and height that we pass to OpenGL |
+ // is a multiple of the block size. |
+ int dataSize = GrCompressedFormatDataSize(desc.fConfig, desc.fWidth, desc.fHeight); |
+ |
+ // We only need the internal format for compressed 2D textures. |
+ GrGLenum internalFormat = 0; |
+ if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NULL)) { |
+ return false; |
+ } |
+ |
+ bool succeeded = true; |
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
+ GL_ALLOC_CALL(this->glInterface(), |
+ CompressedTexImage2D(GR_GL_TEXTURE_2D, |
+ 0, // level |
+ internalFormat, |
+ desc.fWidth, desc.fHeight, |
+ 0, // border |
+ dataSize, |
+ data)); |
+ |
+ GrGLenum error = check_alloc_error(desc, this->glInterface()); |
+ if (error != GR_GL_NO_ERROR) { |
+ succeeded = false; |
+ } |
+ return succeeded; |
+} |
+ |
static bool renderbuffer_storage_msaa(GrGLContext& ctx, |
int sampleCount, |
GrGLenum format, |
@@ -981,6 +1016,80 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, |
return tex; |
} |
+GrTexture* GrGpuGL::onCreateCompressedTexture(const GrTextureDesc& desc, |
+ const void* srcData) { |
+ |
+ if(SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { |
+ return return_null_texture(); |
+ } |
+ |
+ // Make sure that we're not flipping Y. |
+ GrSurfaceOrigin texOrigin = resolve_origin(desc.fOrigin, false); |
+ if (kBottomLeft_GrSurfaceOrigin == texOrigin) { |
+ return return_null_texture(); |
+ } |
+ |
+ GrGLTexture::Desc glTexDesc; |
+ |
+ glTexDesc.fFlags = desc.fFlags; |
+ glTexDesc.fWidth = desc.fWidth; |
+ glTexDesc.fHeight = desc.fHeight; |
+ glTexDesc.fConfig = desc.fConfig; |
+ glTexDesc.fIsWrapped = false; |
+ glTexDesc.fOrigin = texOrigin; |
+ |
+ int maxSize = this->caps()->maxTextureSize(); |
+ if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) { |
+ return return_null_texture(); |
+ } |
+ |
+ GL_CALL(GenTextures(1, &glTexDesc.fTextureID)); |
+ |
+ if (!glTexDesc.fTextureID) { |
+ return return_null_texture(); |
+ } |
+ |
+ this->setScratchTextureUnit(); |
+ GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.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 |
+ // 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(GR_GL_TEXTURE_2D, |
+ GR_GL_TEXTURE_MAG_FILTER, |
+ initialTexParams.fMagFilter)); |
+ GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
+ GR_GL_TEXTURE_MIN_FILTER, |
+ initialTexParams.fMinFilter)); |
+ GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
+ GR_GL_TEXTURE_WRAP_S, |
+ initialTexParams.fWrapS)); |
+ GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
+ GR_GL_TEXTURE_WRAP_T, |
+ initialTexParams.fWrapT)); |
+ |
+ if (!this->uploadCompressedTexData(glTexDesc, srcData)) { |
+ GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID)); |
+ return return_null_texture(); |
+ } |
+ |
+ GrGLTexture* tex; |
+ tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc)); |
+ tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
+#ifdef TRACE_TEXTURE_CREATION |
+ GrPrintf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
+ glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
+#endif |
+ return tex; |
+} |
+ |
namespace { |
const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; |