Revert of Move draw on upload decision in GrGpu (patchset #4 id:50001 of https://codereview.chromium.org/1257073003/)

Reason for revert:
breaking write pixels test on bots

Original issue's description:
> Move draw on upload decision in GrGpu
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/0341b4427e5f037e3b501ed6e57dfdb7b40f150e

TBR=robertphillips@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1260293004
This commit is contained in:
bsalomon 2015-07-28 12:23:26 -07:00 committed by Commit bot
parent efa1ece07e
commit c3fb74693e
7 changed files with 203 additions and 269 deletions

View File

@ -329,96 +329,76 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
uint32_t pixelOpsFlags) {
RETURN_FALSE_IF_ABANDONED
{
GrTexture* texture = NULL;
if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
fGpu->canWriteTexturePixels(texture, srcConfig) &&
(!fCaps->useDrawInsteadOfPartialRenderTargetWrite() || !surface->asRenderTarget() ||
(width == texture->width() && height == texture->height()))) {
if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) &&
surface->surfacePriv().hasPendingIO()) {
this->flush();
}
return fGpu->writeTexturePixels(texture, left, top, width, height,
srcConfig, buffer, rowBytes);
// Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the
// upload is already flushed.
}
}
// Trim the params here so that if we wind up making a temporary surface it can be as small as
// necessary and because GrGpu::getWritePixelsInfo requires it.
// necessary.
if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
GrBytesPerPixel(srcConfig), &left, &top, &width,
&height, &buffer, &rowBytes)) {
return false;
}
bool applyPremulToSrc = false;
// If we didn't do a direct texture write then we upload the pixels to a texture and draw.
GrRenderTarget* renderTarget = surface->asRenderTarget();
if (!renderTarget) {
return false;
}
// We ignore the preferred config unless it is a R/B swap of the src config. In that case
// we will upload the original src data to a scratch texture but we will spoof it as the swapped
// config. This scratch will then have R and B swapped. We correct for this by swapping again
// when drawing the scratch to the dst using a conversion effect.
bool swapRAndB = false;
GrPixelConfig writeConfig = srcConfig;
if (GrPixelConfigSwapRAndB(srcConfig) ==
fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) {
writeConfig = GrPixelConfigSwapRAndB(srcConfig);
swapRAndB = true;
}
GrSurfaceDesc desc;
desc.fWidth = width;
desc.fHeight = height;
desc.fConfig = writeConfig;
SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc,
GrTextureProvider::kApprox_ScratchTexMatch));
if (!texture) {
return false;
}
SkAutoTUnref<const GrFragmentProcessor> fp;
SkMatrix textureMatrix;
textureMatrix.setIDiv(texture->width(), texture->height());
// allocate a tmp buffer and sw convert the pixels to premul
SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
GrPaint paint;
if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
if (!GrPixelConfigIs8888(srcConfig)) {
return false;
}
applyPremulToSrc = true;
}
GrGpu::DrawPreference drawPreference = applyPremulToSrc ?
GrGpu::kCallerPrefersDraw_DrawPreference :
GrGpu::kNoDraw_DrawPreference;
GrGpu::WritePixelTempDrawInfo tempDrawInfo;
if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &drawPreference,
&tempDrawInfo)) {
return false;
}
if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) {
this->flush();
}
SkAutoTUnref<GrTexture> tempTexture;
if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
tempTexture.reset(this->textureProvider()->refScratchTexture(
tempDrawInfo.fTempSurfaceDesc, GrTextureProvider::kApprox_ScratchTexMatch));
if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
return false;
}
}
if (tempTexture) {
SkAutoTUnref<const GrFragmentProcessor> fp;
SkMatrix textureMatrix;
textureMatrix.setIDiv(tempTexture->width(), tempTexture->height());
GrPaint paint;
if (applyPremulToSrc) {
fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture,
tempDrawInfo.fSwapRAndB, textureMatrix));
// If premultiplying was the only reason for the draw, fall back to a straight write.
if (!fp && GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
tempTexture.reset(NULL);
}
}
if (tempTexture) {
fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), texture, swapRAndB,
textureMatrix));
// handle the unpremul step on the CPU if we couldn't create an effect to do it.
if (!fp) {
fp.reset(GrConfigConversionEffect::Create(
paint.getProcessorDataManager(), tempTexture, tempDrawInfo.fSwapRAndB,
GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
if (!fp) {
return false;
}
}
GrRenderTarget* renderTarget = surface->asRenderTarget();
SkASSERT(renderTarget);
if (tempTexture->surfacePriv().hasPendingIO()) {
this->flush();
}
if (!fGpu->writeTexturePixels(tempTexture, 0, 0, width, height,
tempDrawInfo.fTempSurfaceDesc.fConfig, buffer,
rowBytes)) {
return false;
}
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
GrDrawContext* drawContext = this->drawContext();
if (!drawContext) {
return false;
}
paint.addColorProcessor(fp);
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
if (kFlushWrites_PixelOp & pixelOpsFlags) {
this->flushSurfaceWrites(surface);
}
}
}
if (!tempTexture) {
SkASSERT(surface->asTexture());
// allocate a tmp buffer and sw convert the pixels to premul
SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
if (applyPremulToSrc) {
size_t tmpRowBytes = 4 * width;
tmpPixels.reset(width * height);
if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
@ -428,9 +408,45 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
rowBytes = tmpRowBytes;
buffer = tmpPixels.get();
}
return fGpu->writeTexturePixels(surface->asTexture(), left, top, width, height, srcConfig,
buffer, rowBytes);
}
if (!fp) {
fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager(),
texture,
swapRAndB,
GrConfigConversionEffect::kNone_PMConversion,
textureMatrix));
}
// Even if the client told us not to flush, we still flush here. The client may have known that
// writes to the original surface caused no data hazards, but they can't know that the scratch
// we just got is safe.
if (texture->surfacePriv().hasPendingIO()) {
this->flush();
}
if (!fGpu->writeTexturePixels(texture, 0, 0, width, height,
writeConfig, buffer, rowBytes)) {
return false;
}
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
GrDrawContext* drawContext = this->drawContext();
if (!drawContext) {
return false;
}
paint.addColorProcessor(fp);
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
if (kFlushWrites_PixelOp & pixelOpsFlags) {
this->flushSurfaceWrites(surface);
}
return true;
}

View File

@ -232,61 +232,6 @@ void GrGpu::clearStencilClip(const SkIRect& rect,
this->onClearStencilClip(renderTarget, rect, insideClip);
}
bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference* drawPreference,
ReadPixelTempDrawInfo* tempDrawInfo) {
SkASSERT(drawPreference);
SkASSERT(tempDrawInfo);
SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
if (!this->onGetReadPixelsInfo(srcSurface, width, height, rowBytes, readConfig, drawPreference,
tempDrawInfo)) {
return false;
}
// Check to see if we're going to request that the caller draw when drawing is not possible.
if (!srcSurface->asTexture() ||
!this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig, false)) {
// If we don't have a fallback to a straight read then fail.
if (kRequireDraw_DrawPreference == *drawPreference) {
return false;
}
*drawPreference = kNoDraw_DrawPreference;
}
return true;
}
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, int width, int height, size_t rowBytes,
GrPixelConfig srcConfig, DrawPreference* drawPreference,
WritePixelTempDrawInfo* tempDrawInfo) {
SkASSERT(drawPreference);
SkASSERT(tempDrawInfo);
SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
if (this->caps()->useDrawInsteadOfPartialRenderTargetWrite() &&
SkToBool(dstSurface->asRenderTarget()) &&
(width < dstSurface->width() || height < dstSurface->height())) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
if (!this->onGetWritePixelsInfo(dstSurface, width, height, rowBytes, srcConfig, drawPreference,
tempDrawInfo)) {
return false;
}
// Check to see if we're going to request that the caller draw when drawing is not possible.
if (!dstSurface->asRenderTarget() ||
!this->caps()->isConfigTexturable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
// If we don't have a fallback to a straight upload then fail.
if (kRequireDraw_DrawPreference == *drawPreference ||
!this->caps()->isConfigTexturable(srcConfig)) {
return false;
}
*drawPreference = kNoDraw_DrawPreference;
}
return true;
}
bool GrGpu::readPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig config, void* buffer,

View File

@ -173,39 +173,28 @@ public:
kRequireDraw_DrawPreference
};
/**
* Used to negotiate whether and how an intermediate draw should or must be performed before
* a readPixels call. If this returns false then GrGpu could not deduce an intermediate draw
* that would allow a successful readPixels call. The passed width, height, and rowBytes,
* must be non-zero and already reflect clipping to the src bounds.
*/
bool getReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference*, ReadPixelTempDrawInfo*);
/** Info struct returned by getWritePixelsInfo about performing an intermediate draw in order
to write pixels to a GrSurface for either performance or correctness reasons. */
struct WritePixelTempDrawInfo {
/** If the GrGpu is requesting that the caller upload to an intermediate surface and draw
that to the dst then this is the descriptor for the intermediate surface. The caller
should upload the pixels such that the upper left pixel of the upload rect is at 0,0 in
the intermediate surface.*/
GrSurfaceDesc fTempSurfaceDesc;
/** If set, fTempSurfaceDesc's config will be a R/B swap of the src pixel config. The caller
should upload the pixels as is such that R and B will be swapped in the intermediate
surface. When the intermediate is drawn to the dst the shader should swap R/B again
such that the correct swizzle results in the dst. This is done to work around either
performance or API restrictions in the backend 3D API implementation. */
bool fSwapRAndB;
};
/** Used to negotiates whether and how an intermediate draw should or must be performed before
a readPixels call. If this returns false then GrGpu could not deduce an intermediate draw
that would allow a successful readPixels call. */
virtual bool getReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight,
size_t rowBytes, GrPixelConfig readConfig, DrawPreference*,
ReadPixelTempDrawInfo *) = 0;
/**
* Used to negotiate whether and how an intermediate surface should be used to write pixels to
* a GrSurface. If this returns false then GrGpu could not deduce an intermediate draw
* that would allow a successful transfer of the src pixels to the dst. The passed width,
* height, and rowBytes, must be non-zero and already reflect clipping to the dst bounds.
* Gets a preferred 8888 config to use for writing pixel data to a surface with
* config surfaceConfig. The returned config must have at least as many bits per channel as the
* writeConfig param.
*/
bool getWritePixelsInfo(GrSurface* dstSurface, int width, int height, size_t rowBytes,
GrPixelConfig srcConfig, DrawPreference*, WritePixelTempDrawInfo*);
virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
GrPixelConfig surfaceConfig) const {
return writeConfig;
}
/**
* Called before uploading writing pixels to a GrTexture when the src pixel config doesn't
* match the texture's config.
*/
virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const = 0;
/**
* Reads a rectangle of pixels from a render target.
@ -412,16 +401,6 @@ protected:
unsigned int* ref,
unsigned int* mask);
static void ElevateDrawPreference(GrGpu::DrawPreference* preference,
GrGpu::DrawPreference elevation) {
GR_STATIC_ASSERT(GrGpu::kCallerPrefersDraw_DrawPreference > GrGpu::kNoDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kGpuPrefersDraw_DrawPreference >
GrGpu::kCallerPrefersDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kRequireDraw_DrawPreference >
GrGpu::kGpuPrefersDraw_DrawPreference);
*preference = SkTMax(*preference, elevation);
}
const GrTraceMarkerSet& getActiveTraceMarkers() const { return fActiveTraceMarkers; }
Stats fStats;
@ -461,13 +440,6 @@ private:
// overridden by backend-specific derived class to perform the draw call.
virtual void onDraw(const DrawArgs&, const GrNonInstancedVertices&) = 0;
virtual bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight,
size_t rowBytes, GrPixelConfig readConfig, DrawPreference*,
ReadPixelTempDrawInfo*) = 0;
virtual bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, size_t rowBytes,
GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) = 0;
virtual bool onReadPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig,

View File

@ -146,15 +146,14 @@ public:
fCaps.reset(SkNEW_ARGS(GrCaps, (options)));
}
~MockGpu() override {}
bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override {
return true;
}
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
bool getReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference*,
ReadPixelTempDrawInfo*) override { return false; }
bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, size_t rowBytes,
GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) override { return false; }
void buildProgramDesc(GrProgramDesc*,const GrPrimitiveProcessor&,
const GrPipeline&,
const GrBatchTracker&) const override {}

View File

@ -268,6 +268,38 @@ void GrGLGpu::contextAbandoned() {
///////////////////////////////////////////////////////////////////////////////
GrPixelConfig GrGLGpu::preferredWritePixelsConfig(GrPixelConfig writeConfig,
GrPixelConfig surfaceConfig) const {
if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfig) {
return kBGRA_8888_GrPixelConfig;
} else {
return writeConfig;
}
}
bool GrGLGpu::canWriteTexturePixels(const GrTexture* texture, GrPixelConfig srcConfig) const {
if (kIndex_8_GrPixelConfig == srcConfig || kIndex_8_GrPixelConfig == texture->config()) {
return false;
}
if (srcConfig != texture->config() && kGLES_GrGLStandard == this->glStandard()) {
// In general ES2 requires the internal format of the texture and the format of the src
// pixels to match. However, It may or may not be possible to upload BGRA data to a RGBA
// texture. It depends upon which extension added BGRA. The Apple extension allows it
// (BGRA's internal format is RGBA) while the EXT extension does not (BGRA is its own
// internal format).
if (this->glCaps().isConfigTexturable(kBGRA_8888_GrPixelConfig) &&
!this->glCaps().bgraIsInternalFormat() &&
kBGRA_8888_GrPixelConfig == srcConfig &&
kRGBA_8888_GrPixelConfig == texture->config()) {
return true;
} else {
return false;
}
} else {
return true;
}
}
void GrGLGpu::onResetContext(uint32_t resetBits) {
// we don't use the zb at all
if (resetBits & kMisc_GrGLBackendState) {
@ -505,53 +537,6 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
}
////////////////////////////////////////////////////////////////////////////////
bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
size_t rowBytes, GrPixelConfig srcConfig,
DrawPreference* drawPreference,
WritePixelTempDrawInfo* tempDrawInfo) {
if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurface->config())) {
return false;
}
tempDrawInfo->fSwapRAndB = false;
// These settings we will always want if a temp draw is performed. Initially set the config
// to srcConfig, though that may be modified if we decide to do a R/G swap.
tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
tempDrawInfo->fTempSurfaceDesc.fWidth = width;
tempDrawInfo->fTempSurfaceDesc.fHeight = height;
tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
if (configsAreRBSwaps) {
if (!this->caps()->isConfigTexturable(srcConfig)) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwapRAndB = true;
} else if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == srcConfig) {
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwapRAndB = true;
} else if (kGLES_GrGLStandard == this->glStandard() &&
this->glCaps().bgraIsInternalFormat()) {
// The internal format and external formats must match texture uploads so we can't
// swizzle while uploading when BGRA is a distinct internal format.
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwapRAndB = true;
}
}
if (!this->glCaps().unpackFlipYSupport() &&
kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) {
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
}
return true;
}
bool GrGLGpu::onWriteTexturePixels(GrTexture* texture,
int left, int top, int width, int height,
@ -1719,9 +1704,21 @@ static bool read_pixels_pays_for_y_flip(GrRenderTarget* renderTarget, const GrGL
return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == rowBytes;
}
bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
void elevate_draw_preference(GrGpu::DrawPreference* preference, GrGpu::DrawPreference elevation) {
GR_STATIC_ASSERT(GrGpu::kCallerPrefersDraw_DrawPreference > GrGpu::kNoDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kGpuPrefersDraw_DrawPreference >
GrGpu::kCallerPrefersDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kRequireDraw_DrawPreference > GrGpu::kGpuPrefersDraw_DrawPreference);
*preference = SkTMax(*preference, elevation);
}
bool GrGLGpu::getReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference* drawPreference,
ReadPixelTempDrawInfo* tempDrawInfo) {
SkASSERT(drawPreference);
SkASSERT(tempDrawInfo);
SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
if (GrPixelConfigIsCompressed(readConfig)) {
return false;
}
@ -1753,23 +1750,26 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height,
// Better to do a draw with a R/B swap and then read as the original config.
tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
tempDrawInfo->fSwapRAndB = true;
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
elevate_draw_preference(drawPreference, kGpuPrefersDraw_DrawPreference);
} else if (readConfig == kBGRA_8888_GrPixelConfig &&
!this->glCaps().readPixelsSupported(this->glInterface(), GR_GL_BGRA,
GR_GL_UNSIGNED_BYTE, srcConfig)) {
tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
tempDrawInfo->fSwapRAndB = true;
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
elevate_draw_preference(drawPreference, kRequireDraw_DrawPreference);
}
GrRenderTarget* srcAsRT = srcSurface->asRenderTarget();
if (!srcAsRT) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
elevate_draw_preference(drawPreference, kRequireDraw_DrawPreference);
} else if (read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, height, readConfig,
rowBytes)) {
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
elevate_draw_preference(drawPreference, kGpuPrefersDraw_DrawPreference);
}
if (kRequireDraw_DrawPreference == *drawPreference && !srcSurface->asTexture()) {
return false;
}
return true;
}

View File

@ -57,13 +57,15 @@ public:
// Used by GrGLProgram to configure OpenGL state.
void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
bool getReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference*,
ReadPixelTempDrawInfo*) override;
bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
size_t rowBytes, GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) override;
// GrGpu overrides
GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
GrPixelConfig surfaceConfig) const override;
bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override;
bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const override;

View File

@ -27,7 +27,7 @@ static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1,
DEV_H * SK_Scalar1);
static const U8CPU DEV_PAD = 0xee;
static SkPMColor get_canvas_color(int x, int y) {
static SkPMColor getCanvasColor(int x, int y) {
SkASSERT(x >= 0 && x < DEV_W);
SkASSERT(y >= 0 && y < DEV_H);
@ -57,7 +57,7 @@ static SkPMColor get_canvas_color(int x, int y) {
}
// assumes any premu/.unpremul has been applied
static uint32_t pack_color_type(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
static uint32_t packColorType(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
uint32_t r32;
uint8_t* result = reinterpret_cast<uint8_t*>(&r32);
switch (ct) {
@ -80,7 +80,7 @@ static uint32_t pack_color_type(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU
return r32;
}
static uint32_t get_bitmap_color(int x, int y, int w, SkColorType ct, SkAlphaType at) {
static uint32_t getBitmapColor(int x, int y, int w, SkColorType ct, SkAlphaType at) {
int n = y * w + x;
U8CPU b = n & 0xff;
U8CPU g = (n >> 8) & 0xff;
@ -108,16 +108,16 @@ static uint32_t get_bitmap_color(int x, int y, int w, SkColorType ct, SkAlphaTyp
g = SkMulDiv255Ceiling(g, a);
b = SkMulDiv255Ceiling(b, a);
}
return pack_color_type(ct, a, r, g , b);
return packColorType(ct, a, r, g , b);
}
static void fill_canvas(SkCanvas* canvas) {
static void fillCanvas(SkCanvas* canvas) {
SkBitmap bmp;
if (bmp.isNull()) {
bmp.allocN32Pixels(DEV_W, DEV_H);
for (int y = 0; y < DEV_H; ++y) {
for (int x = 0; x < DEV_W; ++x) {
*bmp.getAddr32(x, y) = get_canvas_color(x, y);
*bmp.getAddr32(x, y) = getCanvasColor(x, y);
}
}
}
@ -164,7 +164,7 @@ static SkPMColor convert_to_PMColor(SkColorType ct, SkAlphaType at, uint32_t col
return color;
}
static bool check_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion) {
static bool checkPixel(SkPMColor a, SkPMColor b, bool didPremulConversion) {
if (!didPremulConversion) {
return a == b;
}
@ -219,21 +219,21 @@ static bool check_write(skiatest::Reporter* reporter, SkCanvas* canvas, const Sk
if (writeRect.contains(cx, cy)) {
int bx = cx - writeX;
int by = cy - writeY;
uint32_t bmpColor8888 = get_bitmap_color(bx, by, bitmap.width(),
uint32_t bmpColor8888 = getBitmapColor(bx, by, bitmap.width(),
bmInfo.colorType(), bmInfo.alphaType());
bool mul = (kUnpremul_SkAlphaType == bmInfo.alphaType());
SkPMColor bmpPMColor = convert_to_PMColor(bmInfo.colorType(), bmInfo.alphaType(),
bmpColor8888);
if (!check_pixel(bmpPMColor, canvasPixel, mul)) {
ERRORF(reporter, "Expected canvas pixel at %d, %d to be 0x%08x, got 0x%08x. "
"Write performed premul: %d", cx, cy, bmpPMColor, canvasPixel, mul);
bool check = checkPixel(bmpPMColor, canvasPixel, mul);
REPORTER_ASSERT(reporter, check);
if (!check) {
return false;
}
} else {
SkPMColor testColor = get_canvas_color(cx, cy);
if (canvasPixel != testColor) {
ERRORF(reporter, "Canvas pixel outside write rect at %d, %d changed."
" Should be 0x%08x, got 0x%08x. ", cx, cy, testColor, canvasPixel);
bool check;
SkPMColor testColor = getCanvasColor(cx, cy);
REPORTER_ASSERT(reporter, check = (canvasPixel == testColor));
if (!check) {
return false;
}
}
@ -282,7 +282,7 @@ static const CanvasConfig gCanvasConfigs[] = {
// a custom pixelRef (which also has to specify its rowBytes), so we have to be
// sure that the two rowBytes match (and the infos match).
//
static bool alloc_row_bytes(SkBitmap* bm, const SkImageInfo& info, size_t rowBytes) {
static bool allocRowBytes(SkBitmap* bm, const SkImageInfo& info, size_t rowBytes) {
if (!bm->setInfo(info, rowBytes)) {
return false;
}
@ -328,13 +328,13 @@ static SkSurface* create_surface(const CanvasConfig& c, GrContext* grCtx) {
static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
size_t rowBytes = tightRB ? 0 : 4 * w + 60;
SkImageInfo info = SkImageInfo::Make(w, h, ct, at);
if (!alloc_row_bytes(bm, info, rowBytes)) {
if (!allocRowBytes(bm, info, rowBytes)) {
return false;
}
SkAutoLockPixels alp(*bm);
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
*bm->getAddr32(x, y) = get_bitmap_color(x, y, w, ct, at);
*bm->getAddr32(x, y) = getBitmapColor(x, y, w, ct, at);
}
}
return true;
@ -451,7 +451,7 @@ DEF_GPUTEST(WritePixels, reporter, factory) {
const SkColorType ct = gSrcConfigs[c].fColorType;
const SkAlphaType at = gSrcConfigs[c].fAlphaType;
fill_canvas(&canvas);
fillCanvas(&canvas);
SkBitmap bmp;
REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
rect.height(), SkToBool(tightBmp)));