| Index: src/gpu/gl/GrGLGpu.cpp
|
| diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
|
| index fe803de0a903bfb367116fc5fce42d6ef243a70e..dc50c1429ce44ea940c65a31b85693b1b45d6010 100644
|
| --- a/src/gpu/gl/GrGLGpu.cpp
|
| +++ b/src/gpu/gl/GrGLGpu.cpp
|
| @@ -926,7 +926,7 @@
|
| * @param succeeded Set to true if allocating and populating the texture completed
|
| * without error.
|
| */
|
| -static bool allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc,
|
| +static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc,
|
| const GrGLInterface& interface,
|
| const GrGLCaps& caps,
|
| GrGLenum target,
|
| @@ -934,7 +934,8 @@
|
| GrGLenum externalFormat,
|
| GrGLenum externalType,
|
| const SkTArray<GrMipLevel>& texels,
|
| - int baseWidth, int baseHeight) {
|
| + int baseWidth, int baseHeight,
|
| + bool* succeeded) {
|
| CLEAR_ERROR_BEFORE_ALLOC(&interface);
|
|
|
| bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig);
|
| @@ -954,7 +955,7 @@
|
| desc.fWidth, desc.fHeight));
|
| GrGLenum error = check_alloc_error(desc, &interface);
|
| if (error != GR_GL_NO_ERROR) {
|
| - return false;
|
| + *succeeded = false;
|
| } else {
|
| for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
|
| const void* currentMipData = texels[currentMipLevel].fPixels;
|
| @@ -975,48 +976,33 @@
|
| externalFormat, externalType,
|
| currentMipData));
|
| }
|
| - return true;
|
| + *succeeded = true;
|
| }
|
| } else {
|
| - if (texels.empty()) {
|
| + *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,
|
| - 0,
|
| + currentMipLevel,
|
| internalFormat,
|
| - baseWidth,
|
| - baseHeight,
|
| + currentWidth,
|
| + currentHeight,
|
| 0, // border
|
| externalFormat, externalType,
|
| - nullptr));
|
| + currentMipData));
|
| GrGLenum error = check_alloc_error(desc, &interface);
|
| if (error != GR_GL_NO_ERROR) {
|
| - return false;
|
| - }
|
| - } 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);
|
| - 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) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return true;
|
| + *succeeded = false;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
| /**
|
| @@ -1150,7 +1136,8 @@
|
|
|
| for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
|
| currentMipLevel--) {
|
| - SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || kTransfer_UploadType == uploadType);
|
| + SkASSERT(texelsShallowCopy[currentMipLevel].fPixels ||
|
| + kNewTexture_UploadType == uploadType || kTransfer_UploadType == uploadType);
|
| }
|
|
|
| const GrGLInterface* interface = this->glInterface();
|
| @@ -1166,6 +1153,10 @@
|
| int twoToTheMipLevel = 1 << currentMipLevel;
|
| int currentWidth = SkTMax(1, width / twoToTheMipLevel);
|
| int currentHeight = SkTMax(1, height / twoToTheMipLevel);
|
| +
|
| + if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) {
|
| + continue;
|
| + }
|
|
|
| if (currentHeight > SK_MaxS32 ||
|
| currentWidth > SK_MaxS32) {
|
| @@ -1202,7 +1193,7 @@
|
| bool swFlipY = false;
|
| bool glFlipY = false;
|
|
|
| - if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()) {
|
| + if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
|
| if (caps.unpackFlipYSupport()) {
|
| glFlipY = true;
|
| } else {
|
| @@ -1228,6 +1219,10 @@
|
| char* buffer = (char*)tempStorage.reset(combined_buffer_size);
|
|
|
| for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
|
| + if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) {
|
| + continue;
|
| + }
|
| +
|
| int twoToTheMipLevel = 1 << currentMipLevel;
|
| int currentWidth = SkTMax(1, width / twoToTheMipLevel);
|
| int currentHeight = SkTMax(1, height / twoToTheMipLevel);
|
| @@ -1274,9 +1269,6 @@
|
| } else {
|
| return false;
|
| }
|
| - }
|
| -
|
| - if (!texelsShallowCopy.empty()) {
|
| if (glFlipY) {
|
| GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
|
| }
|
| @@ -1289,10 +1281,10 @@
|
| 0 == left && 0 == top &&
|
| desc.fWidth == width && desc.fHeight == height &&
|
| !desc.fTextureStorageAllocator.fAllocateTextureStorage) {
|
| - succeeded = allocate_and_populate_uncompressed_texture(desc, *interface, caps, target,
|
| - internalFormat, externalFormat,
|
| - externalType, texelsShallowCopy,
|
| - width, height);
|
| + allocate_and_populate_uncompressed_texture(desc, *interface, caps, target,
|
| + internalFormat, externalFormat,
|
| + externalType, texelsShallowCopy,
|
| + width, height, &succeeded);
|
| } else {
|
| if (swFlipY || glFlipY) {
|
| top = desc.fHeight - (top + height);
|
| @@ -1302,6 +1294,9 @@
|
| int twoToTheMipLevel = 1 << currentMipLevel;
|
| int currentWidth = SkTMax(1, width / twoToTheMipLevel);
|
| int currentHeight = SkTMax(1, height / twoToTheMipLevel);
|
| + if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) {
|
| + continue;
|
| + }
|
|
|
| GL_CALL(TexSubImage2D(target,
|
| currentMipLevel,
|
| @@ -1329,6 +1324,8 @@
|
| UploadType uploadType,
|
| int left, int top, int width, int height) {
|
| SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
|
| + SkASSERT(kTransfer_UploadType != uploadType &&
|
| + (texels[0].fPixels || kNewTexture_UploadType != uploadType));
|
|
|
| // No support for software flip y, yet...
|
| SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
|
| @@ -1369,7 +1366,9 @@
|
| return false;
|
| }
|
| for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
|
| - SkASSERT(texels[currentMipLevel].fPixels || kTransfer_UploadType == uploadType);
|
| + if (texels[currentMipLevel].fPixels == nullptr) {
|
| + continue;
|
| + }
|
|
|
| int twoToTheMipLevel = 1 << currentMipLevel;
|
| int currentWidth = SkTMax(1, width / twoToTheMipLevel);
|
| @@ -1848,15 +1847,14 @@
|
| // We do not make SkTArray available outside of Skia,
|
| // and so we do not want to allow mipmaps to external
|
| // allocators just yet.
|
| - SkASSERT(texels.count() < 2);
|
| -
|
| - const void* pixels = nullptr;
|
| - if (!texels.empty()) {
|
| - pixels = texels.begin()->fPixels;
|
| - }
|
| + SkASSERT(texels.count() == 1);
|
| + SkSTArray<1, GrMipLevel> texelsShallowCopy(1);
|
| + texelsShallowCopy.push_back(texels[0]);
|
| +
|
| switch (desc.fTextureStorageAllocator.fAllocateTextureStorage(
|
| desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendObject>(info),
|
| - desc.fWidth, desc.fHeight, desc.fConfig, pixels, desc.fOrigin)) {
|
| + desc.fWidth, desc.fHeight, desc.fConfig, texelsShallowCopy[0].fPixels,
|
| + desc.fOrigin)) {
|
| case GrTextureStorageAllocator::Result::kSucceededAndUploaded:
|
| return true;
|
| case GrTextureStorageAllocator::Result::kFailed:
|
| @@ -1867,7 +1865,7 @@
|
|
|
| if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0,
|
| desc.fWidth, desc.fHeight,
|
| - desc.fConfig, texels)) {
|
| + desc.fConfig, texelsShallowCopy)) {
|
| desc.fTextureStorageAllocator.fDeallocateTextureStorage(
|
| desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendObject>(info));
|
| return false;
|
| @@ -2481,8 +2479,7 @@
|
| desc.fConfig = rtConfig;
|
| desc.fWidth = desc.fHeight = 16;
|
| desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
| - SkAutoTUnref<GrTexture> temp(this->createTexture(desc,
|
| - SkBudgeted::kNo));
|
| + SkAutoTUnref<GrTexture> temp(this->createTexture(desc, SkBudgeted::kNo, nullptr, 0));
|
| if (!temp) {
|
| return false;
|
| }
|
|
|