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

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: Fixing rebase mistake. 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 | « no previous file | 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..13153bc719be72188a445e2a77352326ab652b8b 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -912,11 +912,32 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
}
/**
+ * Determines if TexStorage can be used when creating a texture.
+ *
+ * @param caps The capabilities of the GL device.
+ * @param standard The GL standard in use.
+ * @param desc The surface descriptor for the texture being created.
+ */
+static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standard,
+ const GrSurfaceDesc& desc) {
+ bool canUseTexStorage = caps.texStorageSupport();
+ if (canUseTexStorage && kGL_GrGLStandard == standard) {
+ // 565 is not a sized internal format on desktop GL. So on desktop with
bsalomon 2016/02/26 22:09:54 We now are making most decisions about configs in
cblume 2016/02/27 00:49:54 Done.
+ // 565 we always use an unsized internal format to let the system pick
+ // the best sized format to convert the 565 data to. Since TexStorage
+ // only allows sized internal formats we will instead use TexImage2D.
+ canUseTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
+ }
+
+ return canUseTexStorage;
+}
+
+/**
* Creates storage space for the texture and fills it with texels.
*
* @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 useTexStorage The result of a call to can_use_tex_storage().
* @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 +949,7 @@ static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
*/
static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc,
const GrGLInterface& interface,
+ bool useTexStorage,
GrGLenum target,
GrGLenum internalFormat,
GrGLenum externalFormat,
@@ -936,27 +958,61 @@ 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.
+ 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,
bsalomon 2016/02/26 22:09:54 Won't this cause a problem if we later call glGene
cblume 2016/02/27 00:49:54 The calling sites currently only have useTexStorag
+ 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 +1022,77 @@ 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 useTexStorage The result of a call to can_use_tex_storage().
* @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,
+ bool useTexStorage,
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);
-
+ 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;
+ }
}
}
@@ -1052,6 +1145,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
const GrGLInterface* interface = this->glInterface();
const GrGLCaps& caps = this->glCaps();
+ GrGLStandard standard = this->glStandard();
size_t bpp = GrBytesPerPixel(dataConfig);
@@ -1191,7 +1285,14 @@ 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,
+ bool useTexStorage = can_use_tex_storage(caps, standard, desc);
+ // We can only use TexStorage if we know we will not later change the storage requirements.
+ // This means if we may later want to generate mipmaps, we cannot use TexStorage.
+ // Right now, we cannot know if we will later generate mipmaps or not.
+ // The only time we can use TexStorage is when we already have the
+ // mipmaps.
+ useTexStorage &= texelsShallowCopy.count() > 1;
+ allocate_and_populate_uncompressed_texture(desc, *interface, useTexStorage, target,
internalFormat, externalFormat,
externalType, texelsShallowCopy,
width, height, &succeeded);
@@ -1242,6 +1343,7 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
const GrGLInterface* interface = this->glInterface();
const GrGLCaps& caps = this->glCaps();
+ GrGLStandard standard = this->glStandard();
if (-1 == width) {
width = desc.fWidth;
@@ -1268,8 +1370,15 @@ bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
}
if (kNewTexture_UploadType == uploadType) {
- return allocate_and_populate_compressed_texture(desc, *interface, target, internalFormat,
- texels, width, height);
+ bool useTexStorage = can_use_tex_storage(caps, standard, desc);
+ // We can only use TexStorage if we know we will not later change the storage requirements.
+ // This means if we may later want to generate mipmaps, we cannot use TexStorage.
+ // Right now, we cannot know if we will later generate mipmaps or not.
+ // The only time we can use TexStorage is when we already have the
+ // mipmaps.
+ useTexStorage &= texels.count() > 1;
+ return allocate_and_populate_compressed_texture(desc, *interface, useTexStorage, target,
+ internalFormat, texels, width, height);
} else {
// Paletted textures can't be updated.
if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698