From 9c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5 Mon Sep 17 00:00:00 2001 From: krajcevski Date: Mon, 2 Jun 2014 07:38:14 -0700 Subject: Initial work to get ETC1 data up to the GPU Committed: http://code.google.com/p/skia/source/detail?r=15001 R=bsalomon@google.com, robertphillips@google.com Author: krajcevski@google.com Review URL: https://codereview.chromium.org/302783002 --- src/gpu/gl/GrGpuGL.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) (limited to 'src/gpu/gl/GrGpuGL.cpp') diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 7275f6f73b..7568ba32cf 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); + + // 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; -- cgit v1.2.3