aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-07-11 14:22:35 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-07-12 11:40:15 +0000
commit590533f066035a48df9f78395a80314b559f4714 (patch)
tree49b615883e15aefbaaa6ecba9fd869584889b767
parentc4176a2fa5aab30e5886f05bbe20de225dbe997b (diff)
Plumb raw GrMipLevel* down instead of SkTArray<GrMipLevel> in GrGpu
Change-Id: I34033b6ecb469458eb820cbc01aad8c7bb876312 Reviewed-on: https://skia-review.googlesource.com/22212 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--include/core/SkImage.h2
-rw-r--r--include/private/GrSurfaceProxy.h2
-rw-r--r--src/gpu/GrGpu.cpp56
-rw-r--r--src/gpu/GrGpu.h16
-rw-r--r--src/gpu/GrResourceProvider.cpp13
-rw-r--r--src/gpu/GrResourceProvider.h2
-rw-r--r--src/gpu/GrSurfaceProxy.cpp7
-rw-r--r--src/gpu/SkGr.cpp2
-rw-r--r--src/gpu/SkGr.h2
-rw-r--r--src/gpu/gl/GrGLGpu.cpp67
-rw-r--r--src/gpu/gl/GrGLGpu.h9
-rw-r--r--src/gpu/mock/GrMockGpu.cpp4
-rw-r--r--src/gpu/mock/GrMockGpu.h5
-rw-r--r--src/gpu/mtl/GrMtlGpu.h5
-rw-r--r--src/gpu/vk/GrVkGpu.cpp52
-rw-r--r--src/gpu/vk/GrVkGpu.h6
-rw-r--r--src/image/SkImage.cpp4
-rw-r--r--src/image/SkImage_Gpu.cpp2
18 files changed, 122 insertions, 134 deletions
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index bdb04ff766..11d56026af 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -540,7 +540,7 @@ private:
friend class SkImage_Base;
static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
- const GrMipLevel* texels, int mipLevelCount,
+ const GrMipLevel texels[], int mipLevelCount,
SkBudgeted, SkDestinationSurfaceColorMode);
const int fWidth;
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index c016cfe798..7aa944793a 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -190,7 +190,7 @@ public:
*/
static sk_sp<GrTextureProxy> MakeDeferredMipMap(GrResourceProvider*,
const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const GrMipLevel* texels, int mipLevelCount,
+ const GrMipLevel texels[], int mipLevelCount,
SkDestinationSurfaceColorMode mipColorMode =
SkDestinationSurfaceColorMode::kLegacy);
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index e5877c31a8..ec63eb0a70 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -82,17 +82,20 @@ static GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget)
* Prior to creating a texture, make sure the type of texture being created is
* supported by calling check_texture_creation_params.
*
- * @param caps The capabilities of the GL device.
- * @param desc The descriptor of the texture to create.
- * @param isRT Indicates if the texture can be a render target.
+ * @param caps The capabilities of the GL device.
+ * @param desc The descriptor of the texture to create.
+ * @param isRT Indicates if the texture can be a render target.
+ * @param texels The texel data for the mipmap levels
+ * @param mipLevelCount The number of GrMipLevels in 'texels'
*/
static bool check_texture_creation_params(const GrCaps& caps, const GrSurfaceDesc& desc,
- bool* isRT, const SkTArray<GrMipLevel>& texels) {
+ bool* isRT,
+ const GrMipLevel texels[], int mipLevelCount) {
if (!caps.isConfigTexturable(desc.fConfig)) {
return false;
}
- if (GrPixelConfigIsSint(desc.fConfig) && texels.count() > 1) {
+ if (GrPixelConfigIsSint(desc.fConfig) && mipLevelCount > 1) {
return false;
}
@@ -118,7 +121,7 @@ static bool check_texture_creation_params(const GrCaps& caps, const GrSurfaceDes
}
}
- for (int i = 0; i < texels.count(); ++i) {
+ for (int i = 0; i < mipLevelCount; ++i) {
if (!texels[i].fPixels) {
return false;
}
@@ -127,12 +130,13 @@ static bool check_texture_creation_params(const GrCaps& caps, const GrSurfaceDes
}
sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
GrSurfaceDesc desc = origDesc;
const GrCaps* caps = this->caps();
bool isRT = false;
- bool textureCreationParamsValid = check_texture_creation_params(*caps, desc, &isRT, texels);
+ bool textureCreationParamsValid = check_texture_creation_params(*caps, desc, &isRT,
+ texels, mipLevelCount);
if (!textureCreationParamsValid) {
return nullptr;
}
@@ -143,18 +147,18 @@ sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted
desc.fOrigin = resolve_origin(desc.fOrigin, isRT);
- if (texels.count() && (desc.fFlags & kPerformInitialClear_GrSurfaceFlag)) {
+ if (mipLevelCount && (desc.fFlags & kPerformInitialClear_GrSurfaceFlag)) {
return nullptr;
}
this->handleDirtyContext();
- sk_sp<GrTexture> tex = this->onCreateTexture(desc, budgeted, texels);
+ sk_sp<GrTexture> tex = this->onCreateTexture(desc, budgeted, texels, mipLevelCount);
if (tex) {
if (!caps->reuseScratchTextures() && !isRT) {
tex->resourcePriv().removeScratchKey();
}
fStats.incTextureCreates();
- if (!texels.empty()) {
+ if (mipLevelCount) {
if (texels[0].fPixels) {
fStats.incTextureUploads();
}
@@ -164,17 +168,7 @@ sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted
}
sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted) {
- return this->createTexture(desc, budgeted, SkTArray<GrMipLevel>());
-}
-
-sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const void* level0Data,
- size_t rowBytes) {
- SkASSERT(level0Data);
- GrMipLevel level = { level0Data, rowBytes };
- SkSTArray<1, GrMipLevel> array;
- array.push_back() = level;
- return this->createTexture(desc, budgeted, array);
+ return this->createTexture(desc, budgeted, nullptr, 0);
}
sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex,
@@ -352,9 +346,9 @@ bool GrGpu::readPixels(GrSurface* surface,
bool GrGpu::writePixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, const SkTArray<GrMipLevel>& texels) {
+ GrPixelConfig config, const GrMipLevel texels[], int mipLevelCount) {
SkASSERT(surface);
- if (1 == texels.count()) {
+ if (1 == mipLevelCount) {
// We require that if we are not mipped, then the write region is contained in the surface
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
SkIRect bounds = SkIRect::MakeWH(surface->width(), surface->height());
@@ -366,7 +360,7 @@ bool GrGpu::writePixels(GrSurface* surface,
return false;
}
- for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
if (!texels[currentMipLevel].fPixels ) {
return false;
}
@@ -378,9 +372,9 @@ bool GrGpu::writePixels(GrSurface* surface,
}
this->handleDirtyContext();
- if (this->onWritePixels(surface, left, top, width, height, config, texels)) {
+ if (this->onWritePixels(surface, left, top, width, height, config, texels, mipLevelCount)) {
SkIRect rect = SkIRect::MakeXYWH(left, top, width, height);
- this->didWriteToSurface(surface, &rect, texels.count());
+ this->didWriteToSurface(surface, &rect, mipLevelCount);
fStats.incTextureUploads();
return true;
}
@@ -391,13 +385,9 @@ bool GrGpu::writePixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config, const void* buffer,
size_t rowBytes) {
- GrMipLevel mipLevel;
- mipLevel.fPixels = buffer;
- mipLevel.fRowBytes = rowBytes;
- SkSTArray<1, GrMipLevel> texels;
- texels.push_back(mipLevel);
+ GrMipLevel mipLevel = { buffer, rowBytes };
- return this->writePixels(surface, left, top, width, height, config, texels);
+ return this->writePixels(surface, left, top, width, height, config, &mipLevel, 1);
}
bool GrGpu::transferPixels(GrTexture* texture,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index d413fd62bb..af061da65d 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -104,21 +104,17 @@ public:
* It contains width*height texels. If there is only one
* element and it contains nullptr fPixels, texture data is
* uninitialized.
+ * @param mipLevelCount the number of levels in 'texels'
* @return The texture object if successful, otherwise nullptr.
*/
sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels);
+ const GrMipLevel texels[], int mipLevelCount);
/**
* Simplified createTexture() interface for when there is no initial texel data to upload.
*/
sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted);
- /** Simplified createTexture() interface for when there is only a base level */
- sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const void* level0Data,
- size_t rowBytes);
-
/**
* Implements GrResourceProvider::wrapBackendTexture
*/
@@ -271,11 +267,12 @@ public:
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param texels array of mipmap levels containing texture data
+ * @param mipLevelCount number of levels in 'texels'
*/
bool writePixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config,
- const SkTArray<GrMipLevel>& texels);
+ const GrMipLevel texels[], int mipLevelCount);
/**
* This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
@@ -544,7 +541,8 @@ private:
// onCreateTexture is called.
virtual sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc,
SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) = 0;
+ const GrMipLevel texels[],
+ int mipLevelCount) = 0;
virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
GrSurfaceOrigin,
@@ -589,7 +587,7 @@ private:
virtual bool onWritePixels(GrSurface*,
int left, int top, int width, int height,
GrPixelConfig config,
- const SkTArray<GrMipLevel>& texels) = 0;
+ const GrMipLevel texels[], int mipLevelCount) = 0;
// overridden by backend-specific derived class to perform the texture transfer
virtual bool onTransferPixels(GrTexture*,
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index e8eb4e2020..f3be50b21c 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -74,21 +74,21 @@ bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount
}
sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels,
+ const GrMipLevel texels[], int mipLevelCount,
SkDestinationSurfaceColorMode mipColorMode) {
ASSERT_SINGLE_OWNER
- SkASSERT(texels.count() >= 1);
+ SkASSERT(mipLevelCount >= 1);
if (this->isAbandoned()) {
return nullptr;
}
- if (!validate_desc(desc, *fCaps, texels.count())) {
+ if (!validate_desc(desc, *fCaps, mipLevelCount)) {
return nullptr;
}
- sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels));
+ sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
if (tex) {
tex->texturePriv().setMipColorMode(mipColorMode);
}
@@ -152,10 +152,7 @@ sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc
}
}
- SkTArray<GrMipLevel> texels(1);
- texels.push_back(mipLevel);
-
- sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels));
+ sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, &mipLevel, 1));
return GrSurfaceProxy::MakeWrapped(std::move(tex));
}
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index f9cc2e85bf..a50333da0e 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -68,7 +68,7 @@ public:
sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, uint32_t flags = 0);
sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted,
- const SkTArray<GrMipLevel>& texels,
+ const GrMipLevel texels[], int mipLevelCount,
SkDestinationSurfaceColorMode mipColorMode);
sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&);
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 822d2c9495..abacbcbeca 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -196,7 +196,7 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(
GrResourceProvider* resourceProvider,
const GrSurfaceDesc& desc,
SkBudgeted budgeted,
- const GrMipLevel* texels,
+ const GrMipLevel texels[],
int mipLevelCount,
SkDestinationSurfaceColorMode mipColorMode) {
if (!mipLevelCount) {
@@ -211,17 +211,14 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(
return resourceProvider->createTextureProxy(desc, budgeted, texels[0]);
}
- SkTArray<GrMipLevel> texelsShallowCopy(mipLevelCount);
for (int i = 0; i < mipLevelCount; ++i) {
if (!texels[i].fPixels) {
return nullptr;
}
-
- texelsShallowCopy.push_back(texels[i]);
}
sk_sp<GrTexture> tex(resourceProvider->createTexture(desc, budgeted,
- texelsShallowCopy, mipColorMode));
+ texels, mipLevelCount, mipColorMode));
if (!tex) {
return nullptr;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 0509f8117b..35cd843d96 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -222,7 +222,7 @@ sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
}
sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
- const GrMipLevel* texels,
+ const GrMipLevel texels[],
int mipLevelCount,
SkDestinationSurfaceColorMode colorMode) {
if (!SkImageInfoIsValid(info, colorMode)) {
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 090a384b4a..3ed82a8523 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -227,7 +227,7 @@ sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
* Creates a new texture populated with the mipmap levels.
*/
sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext*, const SkImageInfo&,
- const GrMipLevel* texels,
+ const GrMipLevel texels[],
int mipLevelCount,
SkDestinationSurfaceColorMode colorMode);
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e7c59fa34a..7d169ff444 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -771,7 +771,8 @@ static bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surfac
bool GrGLGpu::onWritePixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[],
+ int mipLevelCount) {
GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
if (!check_write_and_transfer_input(glTex, surface, config)) {
@@ -783,7 +784,7 @@ bool GrGLGpu::onWritePixels(GrSurface* surface,
return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(),
glTex->origin(), glTex->target(), kWrite_UploadType,
- left, top, width, height, config, texels);
+ left, top, width, height, config, texels, mipLevelCount);
}
// For GL_[UN]PACK_ALIGNMENT.
@@ -908,7 +909,7 @@ static bool allocate_and_populate_texture(GrPixelConfig config,
GrGLenum internalFormatForTexStorage,
GrGLenum externalFormat,
GrGLenum externalType,
- const SkTArray<GrMipLevel>& texels,
+ const GrMipLevel texels[], int mipLevelCount,
int baseWidth, int baseHeight) {
CLEAR_ERROR_BEFORE_ALLOC(&interface);
@@ -918,18 +919,18 @@ static bool allocate_and_populate_texture(GrPixelConfig config,
// 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 or are using a format incompatible with MIP maps.
- useTexStorage &= texels.count() > 1 || GrPixelConfigIsSint(config);
+ useTexStorage &= mipLevelCount > 1 || GrPixelConfigIsSint(config);
if (useTexStorage) {
// We never resize or change formats of textures.
GL_ALLOC_CALL(&interface,
- TexStorage2D(target, SkTMax(texels.count(), 1), internalFormatForTexStorage,
+ TexStorage2D(target, SkTMax(mipLevelCount, 1), internalFormatForTexStorage,
baseWidth, baseHeight));
GrGLenum error = CHECK_ALLOC_ERROR(&interface);
if (error != GR_GL_NO_ERROR) {
return false;
} else {
- for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
const void* currentMipData = texels[currentMipLevel].fPixels;
if (currentMipData == nullptr) {
continue;
@@ -951,7 +952,7 @@ static bool allocate_and_populate_texture(GrPixelConfig config,
return true;
}
} else {
- if (texels.empty()) {
+ if (!mipLevelCount) {
GL_ALLOC_CALL(&interface,
TexImage2D(target,
0,
@@ -966,7 +967,7 @@ static bool allocate_and_populate_texture(GrPixelConfig config,
return false;
}
} else {
- for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLevel++) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
int twoToTheMipLevel = 1 << currentMipLevel;
int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
@@ -1015,14 +1016,14 @@ static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLC
bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType,
int left, int top, int width, int height, GrPixelConfig dataConfig,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
SkASSERT(this->caps()->isConfigTexturable(texConfig));
SkDEBUGCODE(
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
SkIRect bounds = SkIRect::MakeWH(texWidth, texHeight);
SkASSERT(bounds.contains(subRect));
)
- SkASSERT(1 == texels.count() ||
+ SkASSERT(1 == mipLevelCount ||
(0 == left && 0 == top && width == texWidth && height == texHeight));
// unbind any previous transfer buffer
@@ -1037,10 +1038,10 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
// Rather than flip in place and alter the incoming data,
// we allocate a new buffer to flip into.
// This means we need to make a non-const shallow copy of texels.
- SkTArray<GrMipLevel> texelsShallowCopy(texels);
+ SkAutoTMalloc<GrMipLevel> texelsShallowCopy(mipLevelCount);
+ memcpy(texelsShallowCopy.get(), texels, mipLevelCount*sizeof(GrMipLevel));
- for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
- currentMipLevel--) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; ++currentMipLevel) {
SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
}
@@ -1075,7 +1076,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
bool swFlipY = false;
bool glFlipY = false;
- if (kBottomLeft_GrSurfaceOrigin == texOrigin && !texelsShallowCopy.empty()) {
+ if (kBottomLeft_GrSurfaceOrigin == texOrigin && mipLevelCount) {
if (caps.unpackFlipYSupport()) {
glFlipY = true;
} else {
@@ -1089,8 +1090,8 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
// find the combined size of all the mip levels and the relative offset of
// each into the collective buffer
size_t combined_buffer_size = 0;
- SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count());
- for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
+ SkTArray<size_t> individual_mip_offsets(mipLevelCount);
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
int twoToTheMipLevel = 1 << currentMipLevel;
int currentWidth = SkTMax(1, width / twoToTheMipLevel);
int currentHeight = SkTMax(1, height / twoToTheMipLevel);
@@ -1100,7 +1101,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
}
char* buffer = (char*)tempStorage.reset(combined_buffer_size);
- for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
int twoToTheMipLevel = 1 << currentMipLevel;
int currentWidth = SkTMax(1, width / twoToTheMipLevel);
int currentHeight = SkTMax(1, height / twoToTheMipLevel);
@@ -1121,7 +1122,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
// TODO: This optimization should be enabled with or without mips.
// For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per
// mip level, before calling glTexImage2D.
- const bool usesMips = texelsShallowCopy.count() > 1;
+ const bool usesMips = mipLevelCount > 1;
if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) {
// can't use this for flipping, only non-neg values allowed. :(
if (rowBytes != trimRowBytes) {
@@ -1152,7 +1153,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
}
}
- if (!texelsShallowCopy.empty()) {
+ if (mipLevelCount) {
if (glFlipY) {
GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
}
@@ -1164,8 +1165,8 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
if (0 == left && 0 == top && texWidth == width && texHeight == height) {
succeeded = allocate_and_populate_texture(
texConfig, *interface, caps, target, internalFormat,
- internalFormatForTexStorage, externalFormat, externalType, texelsShallowCopy,
- width, height);
+ internalFormatForTexStorage, externalFormat, externalType,
+ texelsShallowCopy, mipLevelCount, width, height);
} else {
succeeded = false;
}
@@ -1173,8 +1174,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
if (swFlipY || glFlipY) {
top = texHeight - (top + height);
}
- for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count();
- currentMipLevel++) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
int twoToTheMipLevel = 1 << currentMipLevel;
int currentWidth = SkTMax(1, width / twoToTheMipLevel);
int currentHeight = SkTMax(1, height / twoToTheMipLevel);
@@ -1375,7 +1375,8 @@ static void set_initial_texture_params(const GrGLInterface* interface,
sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& origTexels) {
+ const GrMipLevel texels[],
+ int mipLevelCount) {
// We fail if the MSAA was requested and is not available.
if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
//SkDebugf("MSAA RT requested but not supported on this platform.");
@@ -1383,9 +1384,8 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
}
bool performClear = (desc.fFlags & kPerformInitialClear_GrSurfaceFlag);
- const SkTArray<GrMipLevel>* texels = &origTexels;
- SkTArray<GrMipLevel> zeroLevels;
+ GrMipLevel zeroLevel;
std::unique_ptr<uint8_t[]> zeros;
// TODO: remove the GrPixelConfigIsSint test. This is here because we have yet to add support
// for glClearBuffer* which must be used instead of glClearColor/glClear for integer FBO
@@ -1397,8 +1397,10 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
size_t size = rowSize * desc.fHeight;
zeros.reset(new uint8_t[size]);
memset(zeros.get(), 0, size);
- zeroLevels.push_back(GrMipLevel{zeros.get(), 0});
- texels = &zeroLevels;
+ zeroLevel.fPixels = zeros.get();
+ zeroLevel.fRowBytes = 0;
+ texels = &zeroLevel;
+ mipLevelCount = 1;
performClear = false;
}
@@ -1407,12 +1409,13 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GrGLTexture::IDDesc idDesc;
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
GrGLTexture::TexParams initialTexParams;
- if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams, *texels)) {
+ if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams,
+ texels, mipLevelCount)) {
return return_null_texture();
}
bool wasMipMapDataProvided = false;
- if (texels->count() > 1) {
+ if (mipLevelCount > 1) {
wasMipMapDataProvided = true;
}
@@ -1599,7 +1602,7 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
info->fID = 0;
info->fTarget = GR_GL_TEXTURE_2D;
GL_CALL(GenTextures(1, &(info->fID)));
@@ -1623,7 +1626,7 @@ bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info
}
if (!this->uploadTexData(desc.fConfig, desc.fWidth, desc.fHeight, desc.fOrigin, info->fTarget,
kNewTexture_UploadType, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
- texels)) {
+ texels, mipLevelCount)) {
GL_CALL(DeleteTextures(1, &(info->fID)));
return false;
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 5897f5dae5..9d9c2b002f 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -185,7 +185,8 @@ private:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) override;
+ const GrMipLevel texels[],
+ int mipLevelCount) override;
GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
const void* data) override;
@@ -215,7 +216,7 @@ private:
// The texture parameters are cached in |initialTexParams|.
bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
- const SkTArray<GrMipLevel>& texels);
+ const GrMipLevel texels[], int mipLevelCount);
bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerParams&,
GrTextureProducer::CopyParams*,
@@ -245,7 +246,7 @@ private:
bool onWritePixels(GrSurface*,
int left, int top, int width, int height,
GrPixelConfig config,
- const SkTArray<GrMipLevel>& texels) override;
+ const GrMipLevel texels[], int mipLevelCount) override;
bool onTransferPixels(GrTexture*,
int left, int top, int width, int height,
@@ -379,7 +380,7 @@ private:
bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType, int left,
int top, int width, int height, GrPixelConfig dataConfig,
- const SkTArray<GrMipLevel>& texels);
+ const GrMipLevel texels[], int mipLevelCount);
bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
GrGLRenderTarget::IDDesc*);
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index ae93f8964a..1778ee2ba5 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -52,8 +52,8 @@ GrMockGpu::GrMockGpu(GrContext* context, const GrMockOptions& options,
}
sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) {
- bool hasMipLevels = texels.count() > 1;
+ const GrMipLevel texels[], int mipLevelCount) {
+ bool hasMipLevels = mipLevelCount > 1;
GrMockTextureInfo info;
info.fID = NextInternalTextureID();
if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 25ad5b0fc0..b6ba4942a3 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -67,7 +67,7 @@ private:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted,
- const SkTArray<GrMipLevel>&) override;
+ const GrMipLevel texels[], int mipLevelCount) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
GrSurfaceOrigin,
@@ -103,7 +103,8 @@ private:
bool onWritePixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, const SkTArray<GrMipLevel>& texels) override {
+ GrPixelConfig config,
+ const GrMipLevel texels[], int mipLevelCount) override {
return true;
}
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index dd565aeced..7ec9907675 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -78,7 +78,7 @@ private:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) override {
+ const GrMipLevel texels[], int mipLevelCount) override {
return nullptr;
}
@@ -117,7 +117,8 @@ private:
bool onWritePixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, const SkTArray<GrMipLevel>& texels) override {
+ GrPixelConfig config,
+ const GrMipLevel texels[], int mipLevelCount) override {
return false;
}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 379012709c..87970b5e1c 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -375,14 +375,14 @@ bool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
bool GrVkGpu::onWritePixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture());
if (!vkTex) {
return false;
}
// Make sure we have at least the base level
- if (texels.empty() || !texels.begin()->fPixels) {
+ if (!mipLevelCount || !texels[0].fPixels) {
return false;
}
@@ -394,7 +394,7 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
bool success = false;
bool linearTiling = vkTex->isLinearTiled();
if (linearTiling) {
- if (texels.count() > 1) {
+ if (mipLevelCount > 1) {
SkDebugf("Can't upload mipmap data to linear tiled texture");
return false;
}
@@ -408,16 +408,16 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
this->submitCommandBuffer(kForce_SyncQueue);
}
success = this->uploadTexDataLinear(vkTex, left, top, width, height, config,
- texels.begin()->fPixels, texels.begin()->fRowBytes);
+ texels[0].fPixels, texels[0].fRowBytes);
} else {
- int newMipLevels = texels.count();
int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1;
- if (newMipLevels > currentMipLevels) {
- if (!vkTex->reallocForMipmap(this, newMipLevels)) {
+ if (mipLevelCount > currentMipLevels) {
+ if (!vkTex->reallocForMipmap(this, mipLevelCount)) {
return false;
}
}
- success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config, texels);
+ success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config,
+ texels, mipLevelCount);
}
return success;
@@ -622,15 +622,15 @@ bool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex,
bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
int left, int top, int width, int height,
GrPixelConfig dataConfig,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
SkASSERT(!tex->isLinearTiled());
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
- SkASSERT(1 == texels.count() ||
+ SkASSERT(1 == mipLevelCount ||
(0 == left && 0 == top && width == tex->width() && height == tex->height()));
// We assume that if the texture has mip levels, we either upload to all the levels or just the
// first.
- SkASSERT(1 == texels.count() || texels.count() == (tex->texturePriv().maxMipMapLevel() + 1));
+ SkASSERT(1 == mipLevelCount || mipLevelCount == (tex->texturePriv().maxMipMapLevel() + 1));
if (width == 0 || height == 0) {
return false;
@@ -642,17 +642,17 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
// texels is const.
// But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes.
// Because of this we need to make a non-const shallow copy of texels.
- SkTArray<GrMipLevel> texelsShallowCopy(texels);
+ SkAutoTMalloc<GrMipLevel> texelsShallowCopy(mipLevelCount);
+ memcpy(texelsShallowCopy.get(), texels, mipLevelCount*sizeof(GrMipLevel));
- for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
- currentMipLevel--) {
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; ++currentMipLevel) {
SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
}
// Determine whether we need to flip when we copy into the buffer
- bool flipY = (kBottomLeft_GrSurfaceOrigin == tex->origin() && !texelsShallowCopy.empty());
+ bool flipY = (kBottomLeft_GrSurfaceOrigin == tex->origin() && mipLevelCount);
- SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count());
+ SkTArray<size_t> individualMipOffsets(mipLevelCount);
individualMipOffsets.push_back(0);
size_t combinedBufferSize = width * bpp * height;
int currentWidth = width;
@@ -661,7 +661,7 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
// config. This works with the assumption that the bytes in pixel config is always a power of 2.
SkASSERT((bpp & (bpp - 1)) == 0);
const size_t alignmentMask = 0x3 | (bpp - 1);
- for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
+ for (int currentMipLevel = 1; currentMipLevel < mipLevelCount; currentMipLevel++) {
currentWidth = SkTMax(1, currentWidth/2);
currentHeight = SkTMax(1, currentHeight/2);
@@ -681,13 +681,13 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
return false;
char* buffer = (char*) transferBuffer->map();
- SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count());
+ SkTArray<VkBufferImageCopy> regions(mipLevelCount);
currentWidth = width;
currentHeight = height;
int layerHeight = tex->height();
- for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
- SkASSERT(1 == texelsShallowCopy.count() || currentHeight == layerHeight);
+ for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
+ SkASSERT(1 == mipLevelCount || currentHeight == layerHeight);
const size_t trimRowBytes = currentWidth * bpp;
const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes ?
texelsShallowCopy[currentMipLevel].fRowBytes :
@@ -739,7 +739,7 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
regions.count(),
regions.begin());
transferBuffer->unref();
- if (1 == texelsShallowCopy.count()) {
+ if (1 == mipLevelCount) {
tex->texturePriv().dirtyMipMaps(true);
}
@@ -748,7 +748,7 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
////////////////////////////////////////////////////////////////////////////////
sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>& texels) {
+ const GrMipLevel texels[], int mipLevelCount) {
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
VkFormat pixelFormat;
@@ -780,7 +780,7 @@ sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
// This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is
// requested, this ImageDesc describes the resolved texture. Therefore we always have samples set
// to 1.
- int mipLevels = texels.empty() ? 1 : texels.count();
+ int mipLevels = !mipLevelCount ? 1 : mipLevelCount;
GrVkImage::ImageDesc imageDesc;
imageDesc.fImageType = VK_IMAGE_TYPE_2D;
imageDesc.fFormat = pixelFormat;
@@ -804,10 +804,10 @@ sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
return nullptr;
}
- if (!texels.empty()) {
- SkASSERT(texels.begin()->fPixels);
+ if (mipLevelCount) {
+ SkASSERT(texels[0].fPixels);
if (!this->uploadTexDataOptimal(tex.get(), 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
- texels)) {
+ texels, mipLevelCount)) {
tex->unref();
return nullptr;
}
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 8a3fb09296..ab4df3e5ad 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -174,7 +174,7 @@ private:
void destroyResources();
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const SkTArray<GrMipLevel>&) override;
+ const GrMipLevel texels[], int mipLevelCount) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
GrSurfaceOrigin,
@@ -201,7 +201,7 @@ private:
bool onWritePixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, const SkTArray<GrMipLevel>&) override;
+ GrPixelConfig config, const GrMipLevel texels[], int mipLevelCount) override;
bool onTransferPixels(GrTexture*,
int left, int top, int width, int height,
@@ -246,7 +246,7 @@ private:
bool uploadTexDataOptimal(GrVkTexture* tex,
int left, int top, int width, int height,
GrPixelConfig dataConfig,
- const SkTArray<GrMipLevel>&);
+ const GrMipLevel texels[], int mipLevelCount);
void resolveImage(GrSurface* dst,
GrVkRenderTarget* src,
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 7ec7b35156..9dcf3d74dc 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -327,7 +327,7 @@ sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target,
#if !SK_SUPPORT_GPU
-sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&, const GrMipLevel* texels,
+sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&, const GrMipLevel texels[],
int mipLevelCount, SkBudgeted, SkDestinationSurfaceColorMode) {
return nullptr;
}
@@ -388,7 +388,7 @@ sk_sp<SkImage> SkImage::makeNonTextureImage() const {
///////////////////////////////////////////////////////////////////////////////////////////////////
-sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&, const GrMipLevel* texels,
+sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&, const GrMipLevel texels[],
int mipLevelCount, SkBudgeted) {
return nullptr;
}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 456a080aef..aaaf23953b 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -932,7 +932,7 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info,
- const GrMipLevel* texels, int mipLevelCount,
+ const GrMipLevel texels[], int mipLevelCount,
SkBudgeted budgeted,
SkDestinationSurfaceColorMode colorMode) {
SkASSERT(mipLevelCount >= 1);