Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1570173004: This CL adds glTexStorage support. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Adding TODO comment. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLCaps.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLGpu.cpp
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 071b11383d1691cf134207da8efeaaaefec8fb41..29841331c01d308d45b7c1948db0dfe54547a4a6 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -916,7 +916,7 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
*
* @param desc The surface descriptor for the texture being created.
* @param interface The GL interface in use.
- * @param target The GL target to which the texture is bound
+ * @param caps The capabilities of the GL device.
* @param internalFormat The data format used for the internal storage of the texture.
* @param externalFormat The data format used for the external storage of the texture.
* @param externalType The type of the data used for the external storage of the texture.
@@ -928,6 +928,7 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
*/
static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc,
const GrGLInterface& interface,
+ const GrGLCaps& caps,
GrGLenum target,
GrGLenum internalFormat,
GrGLenum externalFormat,
@@ -936,27 +937,70 @@ static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc
int baseWidth, int baseHeight,
bool* succeeded) {
CLEAR_ERROR_BEFORE_ALLOC(&interface);
- *succeeded = true;
- for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
- int twoToTheMipLevel = 1 << currentMipLevel;
- int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
- int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
- const void* currentMipData = texels[currentMipLevel].fPixels;
- // Even if curremtMipData is nullptr, continue to call TexImage2D.
- // This will allocate texture memory which we can later populate.
+
+ bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig);
+ // We can only use TexStorage if we know we will not later change the storage requirements.
+ // This means if we may later want to add mipmaps, we cannot use TexStorage.
+ // Right now, we cannot know if we will later add mipmaps or not.
+ // The only time we can use TexStorage is when we already have the
+ // mipmaps.
+ useTexStorage &= texels.count() > 1;
+
+ if (useTexStorage) {
+ // We never resize or change formats of textures.
GL_ALLOC_CALL(&interface,
- TexImage2D(target,
- currentMipLevel,
- internalFormat,
- currentWidth,
- currentHeight,
- 0, // border
- externalFormat, externalType,
- currentMipData));
+ TexStorage2D(target,
+ texels.count(),
+ internalFormat,
+ desc.fWidth, desc.fHeight));
GrGLenum error = check_alloc_error(desc, &interface);
if (error != GR_GL_NO_ERROR) {
*succeeded = false;
- break;
+ } else {
+ for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ const void* currentMipData = texels[currentMipLevel].fPixels;
+ if (currentMipData == nullptr) {
+ continue;
+ }
+ int twoToTheMipLevel = 1 << currentMipLevel;
+ int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel);
+ int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel);
+
+ GR_GL_CALL(&interface,
+ TexSubImage2D(target,
+ currentMipLevel,
+ 0, // left
+ 0, // top
+ currentWidth,
+ currentHeight,
+ externalFormat, externalType,
+ currentMipData));
+ }
+ *succeeded = true;
+ }
+ } else {
+ *succeeded = true;
+ for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ int twoToTheMipLevel = 1 << currentMipLevel;
+ int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
+ int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
+ const void* currentMipData = texels[currentMipLevel].fPixels;
+ // Even if curremtMipData is nullptr, continue to call TexImage2D.
+ // This will allocate texture memory which we can later populate.
+ GL_ALLOC_CALL(&interface,
+ TexImage2D(target,
+ currentMipLevel,
+ internalFormat,
+ currentWidth,
+ currentHeight,
+ 0, // border
+ externalFormat, externalType,
+ currentMipData));
+ GrGLenum error = check_alloc_error(desc, &interface);
+ if (error != GR_GL_NO_ERROR) {
+ *succeeded = false;
+ break;
+ }
}
}
}
@@ -966,40 +1010,86 @@ static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc
*
* @param desc The surface descriptor for the texture being created.
* @param interface The GL interface in use.
- * @param target The GL target to which the texture is bound
+ * @param caps The capabilities of the GL device.
* @param internalFormat The data format used for the internal storage of the texture.
* @param texels The texel data of the texture being created.
- * @param baseWidth The width of the texture's base mipmap level
- * @param baseHeight The height of the texture's base mipmap level
*/
static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
const GrGLInterface& interface,
+ const GrGLCaps& caps,
GrGLenum target, GrGLenum internalFormat,
const SkTArray<GrMipLevel>& texels,
int baseWidth, int baseHeight) {
CLEAR_ERROR_BEFORE_ALLOC(&interface);
- for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
- int twoToTheMipLevel = 1 << currentMipLevel;
- int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
- int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
- // Make sure that the width and height that we pass to OpenGL
- // is a multiple of the block size.
- size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, baseHeight);
+ bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig);
+ // We can only use TexStorage if we know we will not later change the storage requirements.
+ // This means if we may later want to add mipmaps, we cannot use TexStorage.
+ // Right now, we cannot know if we will later add mipmaps or not.
+ // The only time we can use TexStorage is when we already have the
+ // mipmaps.
+ useTexStorage &= texels.count() > 1;
+ if (useTexStorage) {
+ // We never resize or change formats of textures.
GL_ALLOC_CALL(&interface,
- CompressedTexImage2D(target,
- currentMipLevel,
- internalFormat,
- currentWidth,
- currentHeight,
- 0, // border
- SkToInt(dataSize),
- texels[currentMipLevel].fPixels));
-
+ TexStorage2D(target,
+ texels.count(),
+ internalFormat,
+ baseWidth, baseHeight));
GrGLenum error = check_alloc_error(desc, &interface);
if (error != GR_GL_NO_ERROR) {
return false;
+ } else {
+ for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ const void* currentMipData = texels[currentMipLevel].fPixels;
+ if (currentMipData == nullptr) {
+ continue;
+ }
+
+ int twoToTheMipLevel = 1 << currentMipLevel;
+ int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
+ int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
+
+ // Make sure that the width and height that we pass to OpenGL
+ // is a multiple of the block size.
+ size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWidth,
+ currentHeight);
+ GR_GL_CALL(&interface, CompressedTexSubImage2D(target,
+ currentMipLevel,
+ 0, // left
+ 0, // top
+ currentWidth,
+ currentHeight,
+ internalFormat,
+ SkToInt(dataSize),
+ currentMipData));
+ }
+ }
+ } else {
+ for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ int twoToTheMipLevel = 1 << currentMipLevel;
+ int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
+ int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
+
+ // Make sure that the width and height that we pass to OpenGL
+ // is a multiple of the block size.
+ size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, baseHeight);
+
+ GL_ALLOC_CALL(&interface,
+ CompressedTexImage2D(target,
+ currentMipLevel,
+ internalFormat,
+ currentWidth,
+ currentHeight,
+ 0, // border
+ SkToInt(dataSize),
+ texels[currentMipLevel].fPixels));
+
+ GrGLenum error = check_alloc_error(desc, &interface);
+ if (error != GR_GL_NO_ERROR) {
+ return false;
+ }
}
}
@@ -1191,7 +1281,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
0 == left && 0 == top &&
desc.fWidth == width && desc.fHeight == height &&
!desc.fTextureStorageAllocator.fAllocateTextureStorage) {
- allocate_and_populate_uncompressed_texture(desc, *interface, target,
+ allocate_and_populate_uncompressed_texture(desc, *interface, caps, target,
internalFormat, externalFormat,
externalType, texelsShallowCopy,
width, height, &succeeded);
@@ -1268,8 +1358,8 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
}
if (kNewTexture_UploadType == uploadType) {
- return allocate_and_populate_compressed_texture(desc, *interface, target, internalFormat,
- texels, width, height);
+ return allocate_and_populate_compressed_texture(desc, *interface, caps, target,
+ internalFormat, texels, width, height);
} else {
// Paletted textures can't be updated.
if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
« no previous file with comments | « src/gpu/gl/GrGLCaps.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698