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
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 7275f6f..7568ba3 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -702,6 +702,41 @@
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 @@
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;