Adding the notion of a volatile bitmap to SkBitmap.
Volatility is a hint that indicates that the contents of a bitmap
are ephemeral. SkGpuDevice will not preserve volatile bitmaps
in its texture cache, and will use textures from a pool of
keyless (recyclable) textures to avoid the performance hit of
texture allocation and release.
A subsequent change is required in webkit in order to take advantage
of this optimization. putImageData, and other methods that create
temporary bitmaps will have to mark their bitmaps as volatile.
before rendering them through skia.
git-svn-id: http://skia.googlecode.com/svn/trunk@1769 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index 480a307..c623952 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -117,7 +117,7 @@
image = storage.get();
}
adjustForPlot(loc, fPlot);
- fTexture->uploadTextureData(loc->fX, loc->fY, dstW, dstH, image);
+ fTexture->uploadTextureData(loc->fX, loc->fY, dstW, dstH, image, 0);
// now tell the caller to skip the top/left BORDER
loc->fX += BORDER;
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
index fec1e74..d36e21b 100644
--- a/gpu/src/GrGLTexture.cpp
+++ b/gpu/src/GrGLTexture.cpp
@@ -17,6 +17,7 @@
#include "GrGLTexture.h"
#include "GrGpuGL.h"
+#include "GrMemory.h"
#define GPUGL static_cast<GrGpuGL*>(getGpu())
@@ -157,7 +158,8 @@
int y,
int width,
int height,
- const void* srcData) {
+ const void* srcData,
+ size_t rowBytes) {
GPUGL->setSpareTextureUnit();
@@ -165,6 +167,37 @@
// (at least without extensions)
GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
+ // in case we need a temporary, trimmed copy of the src pixels
+ GrAutoSMalloc<128 * 128> trimStorage;
+
+ /*
+ * check if our srcData has extra bytes past each row. If so, we need
+ * to trim those off here, since GL doesn't let us pass the rowBytes as
+ * a parameter to glTexImage2D
+ */
+
+ if (GR_GL_SUPPORT_DESKTOP) {
+ if (srcData && rowBytes) {
+ GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
+ rowBytes / fUploadByteCount));
+ }
+ } else {
+ size_t trimRowBytes = width * fUploadByteCount;
+ if (srcData && (trimRowBytes < rowBytes)) {
+ // copy the data into our new storage, skipping the trailing bytes
+ size_t trimSize = height * trimRowBytes;
+ const char* src = (const char*)srcData;
+ char* dst = (char*)trimStorage.realloc(trimSize);
+ for (int y = 0; y < height; y++) {
+ memcpy(dst, src, trimRowBytes);
+ src += rowBytes;
+ dst += trimRowBytes;
+ }
+ // now point srcData to our trimmed version
+ srcData = trimStorage.get();
+ }
+ }
+
// If we need to update textures that are created upside down
// then we have to modify this code to flip the srcData
GrAssert(kTopDown_Orientation == fOrientation);
@@ -173,6 +206,11 @@
GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
fUploadFormat, fUploadType, srcData));
+ if (GR_GL_SUPPORT_DESKTOP) {
+ if (srcData && rowBytes) {
+ GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
+ }
+ }
}
intptr_t GrGLTexture::getTextureHandle() {