From 81beccc4fb1396fe94af15bfce26e68b82b93809 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Mon, 13 Oct 2014 12:32:55 -0700 Subject: [PATCH] Devirtualize read/write pixels on surface. Consolidate read/write funcs in context. Remove support for reading pixels from a surface that's not a target. It's currently broken and neither used nor tested. Review URL: https://codereview.chromium.org/648863002 --- include/gpu/GrContext.h | 53 +----- include/gpu/GrRenderTarget.h | 12 -- include/gpu/GrSurface.h | 20 +- include/gpu/GrTexture.h | 13 -- src/gpu/GrAtlas.cpp | 17 +- src/gpu/GrContext.cpp | 312 +++++++++++++------------------- src/gpu/GrDistanceFieldTextContext.cpp | 7 +- src/gpu/GrRenderTarget.cpp | 32 ---- src/gpu/GrSurface.cpp | 28 +++ src/gpu/GrTexture.cpp | 27 --- src/gpu/SkGr.cpp | 5 +- src/gpu/effects/GrTextureStripAtlas.cpp | 13 +- tests/FloatingPointTextureTest.cpp | 5 +- 13 files changed, 181 insertions(+), 363 deletions(-) diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 6d89d46..2b3b814 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -630,53 +630,8 @@ public: uint32_t pixelOpsFlags = 0); /** - * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified - * rectangle. - * @param target the render target to write into. NULL means the current render target. - * @param left left edge of the rectangle to write (inclusive) - * @param top top edge of the rectangle to write (inclusive) - * @param width width of rectangle to write in pixels. - * @param height height of rectangle to write in pixels. - * @param config the pixel config of the source buffer - * @param buffer memory to read the rectangle from. - * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly - * packed. - * @param pixelOpsFlags see PixelOpsFlags enum above. - * - * @return true if the write succeeded, false if not. The write can fail because of an - * unsupported combination of target and pixel configs. - */ - bool writeRenderTargetPixels(GrRenderTarget* target, - int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0); - - /** - * Reads a rectangle of pixels from a texture. - * @param texture the texture to read from. - * @param left left edge of the rectangle to read (inclusive) - * @param top top edge of the rectangle to read (inclusive) - * @param width width of rectangle to read in pixels. - * @param height height of rectangle to read in pixels. - * @param config the pixel config of the destination buffer - * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly - * packed. - * @param pixelOpsFlags see PixelOpsFlags enum above. - * - * @return true if the read succeeded, false if not. The read can fail because of an unsupported - * pixel config. - */ - bool readTexturePixels(GrTexture* texture, - int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0); - - /** - * Writes a rectangle of pixels to a texture. - * @param texture the render target to read from. + * Writes a rectangle of pixels to a surface. + * @param surface the surface to write to. * @param left left edge of the rectangle to write (inclusive) * @param top top edge of the rectangle to write (inclusive) * @param width width of rectangle to write in pixels. @@ -687,9 +642,9 @@ public: * means rows are tightly packed. * @param pixelOpsFlags see PixelOpsFlags enum above. * @return true if the write succeeded, false if not. The write can fail because of an - * unsupported combination of texture and pixel configs. + * unsupported combination of surface and src configs. */ - bool writeTexturePixels(GrTexture* texture, + bool writeSurfacePixels(GrSurface* surface, int left, int top, int width, int height, GrPixelConfig config, const void* buffer, size_t rowBytes, diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index 4c5ec18..974115d 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -43,18 +43,6 @@ public: return this; } - virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - - virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - // GrRenderTarget /** * If this RT is multisampled, this is the multisample buffer diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 0bbf8d9..ba51f3b 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -87,11 +87,11 @@ public: * @return true if the read succeeded, false if not. The read can fail because of an unsupported * pixel config. */ - virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) = 0; + bool readPixels(int left, int top, int width, int height, + GrPixelConfig config, + void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); /** * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified @@ -106,11 +106,11 @@ public: * packed. * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum. */ - virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) = 0; + bool writePixels(int left, int top, int width, int height, + GrPixelConfig config, + const void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); /** * After this returns any pending writes to the surface will be issued to the backend 3D API. diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h index 43b69ea..28c3fd5 100644 --- a/include/gpu/GrTexture.h +++ b/include/gpu/GrTexture.h @@ -25,19 +25,6 @@ public: */ virtual size_t gpuMemorySize() const SK_OVERRIDE; - // GrSurface overrides - virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - - virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes = 0, - uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - virtual GrTexture* asTexture() SK_OVERRIDE { return this; } virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; } virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return fRenderTarget.get(); } diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp index 0491eed..2da2b00 100644 --- a/src/gpu/GrAtlas.cpp +++ b/src/gpu/GrAtlas.cpp @@ -92,12 +92,9 @@ bool GrPlot::addSubImage(int width, int height, const void* image, SkIPoint16* l // otherwise, just upload the image directly } else if (image) { adjust_for_offset(loc, fOffset); - GrContext* context = fTexture->getContext(); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture"); - context->writeTexturePixels(fTexture, - loc->fX, loc->fY, width, height, - fTexture->config(), image, 0, - GrContext::kDontFlush_PixelOpsFlag); + fTexture->writePixels(loc->fX, loc->fY, width, height, fTexture->config(), image, 0, + GrContext::kDontFlush_PixelOpsFlag); } else { adjust_for_offset(loc, fOffset); } @@ -118,7 +115,6 @@ void GrPlot::uploadToTexture() { if (fDirty) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture"); SkASSERT(fTexture); - GrContext* context = fTexture->getContext(); // We pass the flag that does not force a flush. We assume our caller is // smart and hasn't referenced the part of the texture we're about to update // since the last flush. @@ -126,12 +122,9 @@ void GrPlot::uploadToTexture() { const unsigned char* dataPtr = fPlotData; dataPtr += rowBytes*fDirtyRect.fTop; dataPtr += fBytesPerPixel*fDirtyRect.fLeft; - context->writeTexturePixels(fTexture, - fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop, - fDirtyRect.width(), fDirtyRect.height(), - fTexture->config(), dataPtr, - rowBytes, - GrContext::kDontFlush_PixelOpsFlag); + fTexture->writePixels(fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop, + fDirtyRect.width(), fDirtyRect.height(), fTexture->config(), dataPtr, + rowBytes, GrContext::kDontFlush_PixelOpsFlag); fDirtyRect.setEmpty(); fDirty = false; // If the Plot is nearly full, anything else we add will probably be small and one diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 6ece67f..d5b2116 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -35,6 +35,7 @@ #include "GrTraceMarker.h" #include "GrTracing.h" #include "SkDashPathPriv.h" +#include "SkConfig8888.h" #include "SkGr.h" #include "SkRTConf.h" #include "SkRRect.h" @@ -1244,72 +1245,140 @@ void GrContext::flush(int flagsBitfield) { fFlushToReduceCacheSize = false; } -bool GrContext::writeTexturePixels(GrTexture* texture, +bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes, + const void* inPixels, size_t outRowBytes, void* outPixels) { + SkSrcPixelInfo srcPI; + if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) { + return false; + } + srcPI.fAlphaType = kUnpremul_SkAlphaType; + srcPI.fPixels = inPixels; + srcPI.fRowBytes = inRowBytes; + + SkDstPixelInfo dstPI; + dstPI.fColorType = srcPI.fColorType; + dstPI.fAlphaType = kPremul_SkAlphaType; + dstPI.fPixels = outPixels; + dstPI.fRowBytes = outRowBytes; + + return srcPI.convertPixelsTo(&dstPI, width, height); +} + +bool GrContext::writeSurfacePixels(GrSurface* surface, int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, size_t rowBytes, - uint32_t flags) { - ASSERT_OWNED_RESOURCE(texture); - - if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) { - if (texture->asRenderTarget()) { - return this->writeRenderTargetPixels(texture->asRenderTarget(), - left, top, width, height, - config, buffer, rowBytes, flags); - } else { - return false; + GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, + uint32_t pixelOpsFlags) { + + { + GrTexture* texture = NULL; + if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) && + fGpu->canWriteTexturePixels(texture, srcConfig)) { + + 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. } } - if (!(kDontFlush_PixelOpsFlag & flags) && texture->surfacePriv().hasPendingIO()) { - this->flush(); + // If we didn't do a direct texture write then we upload the pixels to a texture and draw. + GrRenderTarget* renderTarget = surface->asRenderTarget(); + if (NULL == renderTarget) { + return false; } - return fGpu->writeTexturePixels(texture, left, top, width, height, - config, buffer, rowBytes); + // 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; + } - // No need to check the kFlushWrites flag here since we issued the write directly to fGpu. -} + GrTextureDesc desc; + desc.fWidth = width; + desc.fHeight = height; + desc.fConfig = writeConfig; + GrAutoScratchTexture ast(this, desc); + GrTexture* texture = ast.texture(); + if (NULL == texture) { + return false; + } -bool GrContext::readTexturePixels(GrTexture* texture, - int left, int top, int width, int height, - GrPixelConfig config, void* buffer, size_t rowBytes, - uint32_t flags) { - ASSERT_OWNED_RESOURCE(texture); + SkAutoTUnref fp; + SkMatrix textureMatrix; + textureMatrix.setIDiv(texture->width(), texture->height()); - GrRenderTarget* target = texture->asRenderTarget(); - if (target) { - return this->readRenderTargetPixels(target, - left, top, width, height, - config, buffer, rowBytes, - flags); - } else { - // TODO: make this more efficient for cases where we're reading the entire - // texture, i.e., use GetTexImage() instead + // allocate a tmp buffer and sw convert the pixels to premul + SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); - // create scratch rendertarget and read from that - GrAutoScratchTexture ast; - GrTextureDesc desc; - desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = width; - desc.fHeight = height; - desc.fConfig = config; - desc.fOrigin = kTopLeft_GrSurfaceOrigin; - ast.set(this, desc, kExact_ScratchTexMatch); - GrTexture* dst = ast.texture(); - if (dst && (target = dst->asRenderTarget())) { - this->copySurface(target, texture, SkIRect::MakeXYWH(top, left, width, height), - SkIPoint::Make(0,0)); - return this->readRenderTargetPixels(target, - left, top, width, height, - config, buffer, rowBytes, - flags); + if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { + if (!GrPixelConfigIs8888(srcConfig)) { + return false; + } + fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); + // handle the unpremul step on the CPU if we couldn't create an effect to do it. + if (NULL == fp) { + size_t tmpRowBytes = 4 * width; + tmpPixels.reset(width * height); + if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes, + tmpPixels.get())) { + return false; + } + rowBytes = tmpRowBytes; + buffer = tmpPixels.get(); } + } + if (NULL == fp) { + fp.reset(GrConfigConversionEffect::Create(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; } -} -#include "SkConfig8888.h" + SkMatrix matrix; + matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); + + // This function can be called in the midst of drawing another object (e.g., when uploading a + // SW-rasterized clip while issuing a draw). So we push the current geometry state before + // drawing a rect to the render target. + // The bracket ensures we pop the stack if we wind up flushing below. + { + GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL); + GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit, + &matrix); + GrDrawState* drawState = drawTarget->drawState(); + drawState->addColorProcessor(fp); + drawState->setRenderTarget(renderTarget); + drawState->disableState(GrDrawState::kClip_StateBit); + drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); + } + + if (kFlushWrites_PixelOp & pixelOpsFlags) { + this->flushSurfaceWrites(surface); + } + + return true; +} // toggles between RGBA and BGRA static SkColorType toggle_colortype32(SkColorType ct) { @@ -1372,8 +1441,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target, GrTexture* src = target->asTexture(); GrAutoScratchTexture ast; if (src && (swapRAndB || unpremul || flipY)) { - // Make the scratch a render target because we don't have a robust readTexturePixels as of - // yet. It calls this function. + // Make the scratch a render so we can read its pixels. GrTextureDesc desc; desc.fFlags = kRenderTarget_GrTextureFlagBit; desc.fWidth = width; @@ -1508,144 +1576,6 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe } } -bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, - int left, int top, int width, int height, - GrPixelConfig srcConfig, - const void* buffer, - size_t rowBytes, - uint32_t pixelOpsFlags) { - ASSERT_OWNED_RESOURCE(renderTarget); - - if (NULL == renderTarget) { - renderTarget = fRenderTarget.get(); - if (NULL == renderTarget) { - return false; - } - } - - // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on - // desktop GL). - - // We will always call some form of writeTexturePixels and we will pass our flags on to it. - // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't - // set.) - - // If the RT is also a texture and we don't have to premultiply then take the texture path. - // We expect to be at least as fast or faster since it doesn't use an intermediate texture as - // we do below. - -#if !defined(SK_BUILD_FOR_MAC) - // At least some drivers on the Mac get confused when glTexImage2D is called on a texture - // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or - // HW is affected. - if (renderTarget->asTexture() && !(kUnpremul_PixelOpsFlag & pixelOpsFlags) && - fGpu->canWriteTexturePixels(renderTarget->asTexture(), srcConfig)) { - return this->writeTexturePixels(renderTarget->asTexture(), - left, top, width, height, - srcConfig, buffer, rowBytes, pixelOpsFlags); - } -#endif - - // 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; - } - - GrTextureDesc desc; - desc.fWidth = width; - desc.fHeight = height; - desc.fConfig = writeConfig; - GrAutoScratchTexture ast(this, desc); - GrTexture* texture = ast.texture(); - if (NULL == texture) { - return false; - } - - SkAutoTUnref 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); - - if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { - if (!GrPixelConfigIs8888(srcConfig)) { - return false; - } - fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); - // handle the unpremul step on the CPU if we couldn't create an effect to do it. - if (NULL == fp) { - SkSrcPixelInfo srcPI; - if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) { - return false; - } - srcPI.fAlphaType = kUnpremul_SkAlphaType; - srcPI.fPixels = buffer; - srcPI.fRowBytes = rowBytes; - - tmpPixels.reset(width * height); - - SkDstPixelInfo dstPI; - dstPI.fColorType = srcPI.fColorType; - dstPI.fAlphaType = kPremul_SkAlphaType; - dstPI.fPixels = tmpPixels.get(); - dstPI.fRowBytes = 4 * width; - - if (!srcPI.convertPixelsTo(&dstPI, width, height)) { - return false; - } - - buffer = tmpPixels.get(); - rowBytes = 4 * width; - } - } - if (NULL == fp) { - fp.reset(GrConfigConversionEffect::Create(texture, - swapRAndB, - GrConfigConversionEffect::kNone_PMConversion, - textureMatrix)); - } - - if (!this->writeTexturePixels(texture, - 0, 0, width, height, - writeConfig, buffer, rowBytes, - pixelOpsFlags & ~kUnpremul_PixelOpsFlag)) { - return false; - } - - SkMatrix matrix; - matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); - - - // This function can be called in the midst of drawing another object (e.g., when uploading a - // SW-rasterized clip while issuing a draw). So we push the current geometry state before - // drawing a rect to the render target. - // The bracket ensures we pop the stack if we wind up flushing below. - { - GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL); - GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit, - &matrix); - GrDrawState* drawState = drawTarget->drawState(); - drawState->addColorProcessor(fp); - drawState->setRenderTarget(renderTarget); - drawState->disableState(GrDrawState::kClip_StateBit); - drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); - } - - if (kFlushWrites_PixelOp & pixelOpsFlags) { - this->flush(); - } - - return true; -} - void GrContext::flushSurfaceWrites(GrSurface* surface) { if (surface->surfacePriv().hasPendingWrite()) { this->flush(); diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index a1f5ce6..183b83c 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -190,10 +190,9 @@ static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, return; } - context->writeTexturePixels(*gammaTexture, - 0, 0, width, height, - (*gammaTexture)->config(), data.get(), 0, - GrContext::kDontFlush_PixelOpsFlag); + (*gammaTexture)->writePixels(0, 0, width, height, + (*gammaTexture)->config(), data.get(), 0, + GrContext::kDontFlush_PixelOpsFlag); } } diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index b976332..7ed70c9 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -13,38 +13,6 @@ #include "GrGpu.h" #include "GrStencilBuffer.h" -bool GrRenderTarget::readPixels(int left, int top, int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes, - uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (NULL == context) { - return false; - } - return context->readRenderTargetPixels(this, - left, top, width, height, - config, buffer, rowBytes, - pixelOpsFlags); -} - -void GrRenderTarget::writePixels(int left, int top, int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes, - uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (NULL == context) { - return; - } - context->writeRenderTargetPixels(this, - left, top, width, height, - config, buffer, rowBytes, - pixelOpsFlags); -} - void GrRenderTarget::resolve() { // go through context so that all necessary flushing occurs GrContext* context = this->getContext(); diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index d067f07..0aa5f68 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -13,6 +13,34 @@ #include "SkImageEncoder.h" #include +bool GrSurface::writePixels(int left, int top, int width, int height, + GrPixelConfig config, const void* buffer, size_t rowBytes, + uint32_t pixelOpsFlags) { + // go through context so that all necessary flushing occurs + GrContext* context = this->getContext(); + if (NULL == context) { + return false; + } + return context->writeSurfacePixels(this, left, top, width, height, config, buffer, rowBytes, + pixelOpsFlags); +} + +bool GrSurface::readPixels(int left, int top, int width, int height, + GrPixelConfig config, void* buffer, size_t rowBytes, + uint32_t pixelOpsFlags) { + // go through context so that all necessary flushing occurs + GrContext* context = this->getContext(); + if (NULL == context) { + return false; + } + GrRenderTarget* target = this->asRenderTarget(); + if (target) { + return context->readRenderTargetPixels(target, left, top, width, height, config, buffer, + rowBytes, pixelOpsFlags); + } + return false; +} + SkImageInfo GrSurface::info() const { SkColorType colorType; if (!GrPixelConfig2ColorType(this->config(), &colorType)) { diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index aac91c5..b49e207 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -53,33 +53,6 @@ size_t GrTexture::gpuMemorySize() const { return textureSize; } -bool GrTexture::readPixels(int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes, uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (NULL == context) { - return false; - } - return context->readTexturePixels(this, - left, top, width, height, - config, buffer, rowBytes, - pixelOpsFlags); -} - -void GrTexture::writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes, uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (NULL == context) { - return; - } - context->writeTexturePixels(this, - left, top, width, height, - config, buffer, rowBytes, - pixelOpsFlags); -} void GrTexture::onRelease() { SkASSERT(!this->texturePriv().isSetFlag((GrTextureFlags) kReturnToCache_FlagBit)); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index d943545..4a2cf47 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -254,9 +254,8 @@ static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa yuvDesc.fHeight = yuvSizes[i].fHeight; yuvTextures[i].set(ctx, yuvDesc); if ((NULL == yuvTextures[i].texture()) || - !ctx->writeTexturePixels(yuvTextures[i].texture(), - 0, 0, yuvDesc.fWidth, yuvDesc.fHeight, - yuvDesc.fConfig, planes[i], rowBytes[i])) { + !yuvTextures[i].texture()->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, + yuvDesc.fConfig, planes[i], rowBytes[i])) { return NULL; } } diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index 9755ccd..64ee711 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -155,13 +155,12 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) { // Pass in the kDontFlush flag, since we know we're writing to a part of this texture // that is not currently in use - fDesc.fContext->writeTexturePixels(fTexture, - 0, rowNumber * fDesc.fRowHeight, - fDesc.fWidth, fDesc.fRowHeight, - SkImageInfo2GrPixelConfig(data.info()), - data.getPixels(), - data.rowBytes(), - GrContext::kDontFlush_PixelOpsFlag); + fTexture->writePixels(0, rowNumber * fDesc.fRowHeight, + fDesc.fWidth, fDesc.fRowHeight, + SkImageInfo2GrPixelConfig(data.info()), + data.getPixels(), + data.rowBytes(), + GrContext::kDontFlush_PixelOpsFlag); } SkASSERT(rowNumber >= 0); diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp index d367659..9ca34c8 100644 --- a/tests/FloatingPointTextureTest.cpp +++ b/tests/FloatingPointTextureTest.cpp @@ -68,9 +68,8 @@ DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) { } // write square - context->writeTexturePixels(fpTexture, 0, 0, DEV_W, DEV_H, desc.fConfig, - controlPixelData, 0); - context->readTexturePixels(fpTexture, 0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer, 0); + fpTexture->writePixels(0, 0, DEV_W, DEV_H, desc.fConfig, controlPixelData, 0); + fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer, 0); for (int j = 0; j < FP_CONTROL_ARRAY_SIZE; ++j) { REPORTER_ASSERT(reporter, readBuffer[j] == controlPixelData[j]); } -- 2.7.4