aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar krajcevski <krajcevski@google.com>2014-06-11 16:07:50 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-06-11 16:07:51 -0700
commit145d48c4ccf1024ce0878e5110c0be7d414b7dde (patch)
tree7301f5e38528253daad4e59450004a43594ce9dc /src
parent6b28120e4c5e05a68e4947a3558f8d6615720a6e (diff)
Allow compressed texture data to be updated.
R=robertphillips@google.com Author: krajcevski@google.com Review URL: https://codereview.chromium.org/326383003
Diffstat (limited to 'src')
-rw-r--r--src/gpu/gl/GrGpuGL.cpp82
-rw-r--r--src/gpu/gl/GrGpuGL.h12
2 files changed, 74 insertions, 20 deletions
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 12938f16a5..f1b6da8261 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -201,8 +201,7 @@ GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig writeConfig,
}
bool GrGpuGL::canWriteTexturePixels(const GrTexture* texture, GrPixelConfig srcConfig) const {
- if (kIndex_8_GrPixelConfig == srcConfig || kIndex_8_GrPixelConfig == texture->config() ||
- GrPixelConfigIsCompressed(srcConfig) || GrPixelConfigIsCompressed(texture->config())) {
+ if (kIndex_8_GrPixelConfig == srcConfig || kIndex_8_GrPixelConfig == texture->config()) {
return false;
}
if (srcConfig != texture->config() && kGLES_GrGLStandard == this->glStandard()) {
@@ -478,14 +477,24 @@ bool GrGpuGL::onWriteTexturePixels(GrTexture* texture,
desc.fTextureID = glTex->textureID();
desc.fOrigin = glTex->origin();
- if (this->uploadTexData(desc, false,
- left, top, width, height,
- config, buffer, rowBytes)) {
+ bool success = false;
+ if (GrPixelConfigIsCompressed(desc.fConfig)) {
+ // We check that config == desc.fConfig in GrGpuGL::canWriteTexturePixels()
+ SkASSERT(config == desc.fConfig);
+ success = this->uploadCompressedTexData(desc, buffer, false,
+ left, top, width, height);
+ } else {
+ success = this->uploadTexData(desc, false,
+ left, top, width, height,
+ config, buffer, rowBytes);
+ }
+
+ if (success) {
texture->impl()->dirtyMipMaps(true);
return true;
- } else {
- return false;
}
+
+ return false;
}
namespace {
@@ -703,16 +712,41 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
return succeeded;
}
+// TODO: This function is using a lot of wonky semantics like, if width == -1
+// then set width = desc.fWdith ... blah. A better way to do it might be to
+// create a CompressedTexData struct that takes a desc/ptr and figures out
+// 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 GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc,
- const void* data) {
- SkASSERT(NULL != data);
+ const void* data,
+ bool isNewTexture,
+ int left, int top, int width, int height) {
+ SkASSERT(NULL != data || isNewTexture);
// No support for software flip y, yet...
SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
+ if (-1 == width) {
+ width = desc.fWidth;
+ }
+#ifdef SK_DEBUG
+ else {
+ SkASSERT(width <= desc.fWidth);
+ }
+#endif
+
+ if (-1 == height) {
+ height = desc.fHeight;
+ }
+#ifdef SK_DEBUG
+ else {
+ SkASSERT(height <= desc.fHeight);
+ }
+#endif
+
// 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);
+ int dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
// We only need the internal format for compressed 2D textures.
GrGLenum internalFormat = 0;
@@ -722,14 +756,26 @@ bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc,
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));
+
+ if (isNewTexture) {
+ GL_ALLOC_CALL(this->glInterface(),
+ CompressedTexImage2D(GR_GL_TEXTURE_2D,
+ 0, // level
+ internalFormat,
+ width, height,
+ 0, // border
+ dataSize,
+ data));
+ } else {
+ GL_ALLOC_CALL(this->glInterface(),
+ CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
+ 0, // level
+ left, top,
+ width, height,
+ internalFormat,
+ dataSize,
+ data));
+ }
GrGLenum error = check_alloc_error(desc, this->glInterface());
if (error != GR_GL_NO_ERROR) {
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index e50ff9b2ea..a2c636d2aa 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -274,9 +274,17 @@ private:
const void* data,
size_t rowBytes);
- // helper for onCreateCompressedTexture
+ // helper for onCreateCompressedTexture. If width and height are
+ // set to -1, then this function will use desc.fWidth and desc.fHeight
+ // for the size of the data. The isNewTexture flag should be set to true
+ // whenever a new texture needs to be created. Otherwise, we assume that
+ // the texture is already in GPU memory and that it's going to be updated
+ // with new data.
bool uploadCompressedTexData(const GrGLTexture::Desc& desc,
- const void* data);
+ const void* data,
+ bool isNewTexture = true,
+ int left = 0, int top = 0,
+ int width = -1, int height = -1);
bool createRenderTargetObjects(int width, int height,
GrGLuint texID,