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>
This commit is contained in:
Robert Phillips 2017-07-11 14:22:35 -04:00 committed by Skia Commit-Bot
parent c4176a2fa5
commit 590533f066
18 changed files with 122 additions and 134 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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*,

View File

@ -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));
}

View File

@ -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&);

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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*);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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);