Revert "Refactor trimming logic for read/writePixels()"
This reverts commit 977f64cbfad1ecd7fd4b1231c694c7e828fda1f0.
Reason for revert: Triggering nanobench asserts
Original change's description:
> Refactor trimming logic for read/writePixels()
>
> (1) Move trimming logic into Bitmap/Pixmap level for
> raster. Everything goes through here, so we'll
> only do the work once.
> (2) This means it also goes to GPU level.
> (3) Always use SkReadPixelsRec rather than inlining
> the logic.
> (4) Create an SkWritePixelsRec to encapsulate write
> trimming.
> (5) Disabled kIndex8 as a dst - always.
>
> BUG=skia:6021
>
> Change-Id: I748f50c3b726f7c6de5462e2b1ccb54bc387a510
> Reviewed-on: https://skia-review.googlesource.com/7326
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Matt Sarett <msarett@google.com>
>
TBR=msarett@google.com,brianosman@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:6021
Change-Id: If9aacc6ce8b20e3dfe8a0f22ebca653f28356175
Reviewed-on: https://skia-review.googlesource.com/7379
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 76f4a70..0375ab7 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -30,6 +30,7 @@
#include "SkRadialShadowMapShader.h"
#include "SkRasterClip.h"
#include "SkRasterHandleAllocator.h"
+#include "SkReadPixelsRec.h"
#include "SkRRect.h"
#include "SkShadowPaintFilterCanvas.h"
#include "SkShadowShader.h"
@@ -857,6 +858,10 @@
}
bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) {
+ if (kUnknown_SkColorType == bitmap->colorType()) {
+ return false;
+ }
+
bool weAllocated = false;
if (nullptr == bitmap->pixelRef()) {
if (!bitmap->tryAllocPixels()) {
@@ -903,8 +908,15 @@
if (!device) {
return false;
}
+ const SkISize size = this->getBaseLayerSize();
- return device->readPixels(dstInfo, dstP, rowBytes, x, y);
+ SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y);
+ if (!rec.trim(size.width(), size.height())) {
+ return false;
+ }
+
+ // The device can assert that the requested area is always contained in its bounds
+ return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY);
}
bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
@@ -916,30 +928,49 @@
return false;
}
-bool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes,
+bool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes,
int x, int y) {
+ switch (origInfo.colorType()) {
+ case kUnknown_SkColorType:
+ case kIndex_8_SkColorType:
+ return false;
+ default:
+ break;
+ }
+ if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) {
+ return false;
+ }
+
+ const SkISize size = this->getBaseLayerSize();
+ SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height());
+ if (!target.intersect(0, 0, size.width(), size.height())) {
+ return false;
+ }
+
SkBaseDevice* device = this->getDevice();
if (!device) {
return false;
}
- // This check gives us an early out and prevents generation ID churn on the surface.
- // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec.
- SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height());
- if (!srcRect.intersect(0, 0, device->width(), device->height())) {
- return false;
- }
+ // the intersect may have shrunk info's logical size
+ const SkImageInfo info = origInfo.makeWH(target.width(), target.height());
- // Tell our owning surface to bump its generation ID.
- const bool completeOverwrite =
- srcRect.size() == SkISize::Make(device->width(), device->height());
+ // if x or y are negative, then we have to adjust pixels
+ if (x > 0) {
+ x = 0;
+ }
+ if (y > 0) {
+ y = 0;
+ }
+ // here x,y are either 0 or negative
+ pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel());
+
+ // Tell our owning surface to bump its generation ID
+ const bool completeOverwrite = info.dimensions() == size;
this->predrawNotify(completeOverwrite);
- // This can still fail, most notably in the case of a invalid color type or alpha type
- // conversion. We could pull those checks into this function and avoid the unnecessary
- // generation ID bump. But then we would be performing those checks twice, since they
- // are also necessary at the bitmap/pixmap entry points.
- return device->writePixels(srcInfo, pixels, rowBytes, x, y);
+ // The device can assert that the requested area is always contained in its bounds
+ return device->writePixels(info, pixels, rowBytes, target.x(), target.y());
}
//////////////////////////////////////////////////////////////////////////////