Revert "Reland "implement SkPixmap::erase() with draws""

This reverts commit 4a9631c186.

Reason for revert: Chrome for Android in roll?
https://chromium-review.googlesource.com/c/chromium/src/+/1231494

Original change's description:
> Reland "implement SkPixmap::erase() with draws"
> 
> This is a reland of 42f29f1181
> 
> The original had to be reverted because of a buggy Chromium unit test,
> now fixed.  I also took the opportunity to implement this with SkDraw
> rather than SkCanvas.
> 
> Original change's description:
> > implement SkPixmap::erase() with draws
> >
> > I don't want to have to maintain yet another switch on SkColorType.
> >
> > This should also make color management a bit clearer?
> >
> > Change-Id: I1508e0c30670b1987972f7eeba2dd6d23591c531
> > Reviewed-on: https://skia-review.googlesource.com/154862
> > Commit-Queue: Mike Klein <mtklein@google.com>
> > Reviewed-by: Brian Osman <brianosman@google.com>
> 
> Change-Id: I6bc071e8a6025723d47f2ad5f6fb7f8fa5dccc2b
> Reviewed-on: https://skia-review.googlesource.com/155240
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: Mike Klein <mtklein@google.com>

TBR=mtklein@google.com,brianosman@google.com,reed@google.com

Change-Id: I1ce2ae01253e95da28f7d5b4bd82b59775e9fef8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/155403
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2018-09-18 21:22:37 +00:00 committed by Skia Commit-Bot
parent c03a86affc
commit 774b566c13

View File

@ -8,10 +8,10 @@
#include "SkPixmap.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorData.h"
#include "SkConvertPixels.h"
#include "SkData.h"
#include "SkDraw.h"
#include "SkHalf.h"
#include "SkImageInfoPriv.h"
#include "SkImageShader.h"
@ -19,7 +19,6 @@
#include "SkNx.h"
#include "SkPM4f.h"
#include "SkPixmapPriv.h"
#include "SkRasterClip.h"
#include "SkReadPixelsRec.h"
#include "SkSurface.h"
#include "SkTemplates.h"
@ -98,30 +97,188 @@ bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t ds
return true;
}
bool SkPixmap::erase(SkColor color, const SkIRect& area) const {
return this->erase(SkColor4f::FromColor(color), &area);
static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b) {
unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) |
(SkR32To4444(r) << SK_R4444_SHIFT) |
(SkG32To4444(g) << SK_G4444_SHIFT) |
(SkB32To4444(b) << SK_B4444_SHIFT);
return SkToU16(pixel);
}
bool SkPixmap::erase(const SkColor4f& color, const SkIRect* subset) const {
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
paint.setColor4f(color, this->colorSpace());
SkIRect clip = this->bounds();
if (subset && !clip.intersect(*subset)) {
bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const {
if (nullptr == fPixels) {
return false;
}
SkIRect area;
if (!area.intersect(this->bounds(), inArea)) {
return false;
}
SkRasterClip rc{clip};
SkDraw draw;
draw.fDst = *this;
draw.fMatrix = &SkMatrix::I();
draw.fRC = &rc;
U8CPU a = SkColorGetA(color);
U8CPU r = SkColorGetR(color);
U8CPU g = SkColorGetG(color);
U8CPU b = SkColorGetB(color);
draw.drawPaint(paint);
int height = area.height();
const int width = area.width();
const int rowBytes = this->rowBytes();
if (color == 0
&& width == this->rowBytesAsPixels()
&& inArea == this->bounds()) {
// All formats represent SkColor(0) as byte 0.
memset(this->writable_addr(), 0, (int64_t)height * rowBytes);
return true;
}
switch (this->colorType()) {
case kGray_8_SkColorType: {
if (255 != a) {
r = SkMulDiv255Round(r, a);
g = SkMulDiv255Round(g, a);
b = SkMulDiv255Round(b, a);
}
int gray = SkComputeLuminance(r, g, b);
uint8_t* p = this->writable_addr8(area.fLeft, area.fTop);
while (--height >= 0) {
memset(p, gray, width);
p += rowBytes;
}
break;
}
case kAlpha_8_SkColorType: {
uint8_t* p = this->writable_addr8(area.fLeft, area.fTop);
while (--height >= 0) {
memset(p, a, width);
p += rowBytes;
}
break;
}
case kARGB_4444_SkColorType:
case kRGB_565_SkColorType: {
uint16_t* p = this->writable_addr16(area.fLeft, area.fTop);
uint16_t v;
// make rgb premultiplied
if (255 != a) {
r = SkMulDiv255Round(r, a);
g = SkMulDiv255Round(g, a);
b = SkMulDiv255Round(b, a);
}
if (kARGB_4444_SkColorType == this->colorType()) {
v = pack_8888_to_4444(a, r, g, b);
} else {
v = SkPackRGB16(r >> (8 - SK_R16_BITS),
g >> (8 - SK_G16_BITS),
b >> (8 - SK_B16_BITS));
}
while (--height >= 0) {
sk_memset16(p, v, width);
p = (uint16_t*)((char*)p + rowBytes);
}
break;
}
case kRGB_888x_SkColorType:
a = 255; // then fallthrough to 8888
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType: {
uint32_t* p = this->writable_addr32(area.fLeft, area.fTop);
if (255 != a && kPremul_SkAlphaType == this->alphaType()) {
r = SkMulDiv255Round(r, a);
g = SkMulDiv255Round(g, a);
b = SkMulDiv255Round(b, a);
}
uint32_t v = kBGRA_8888_SkColorType == this->colorType()
? SkPackARGB_as_BGRA(a, r, g, b) // bgra 8888
: SkPackARGB_as_RGBA(a, r, g, b); // rgba 8888 or rgb 888
while (--height >= 0) {
sk_memset32(p, v, width);
p = (uint32_t*)((char*)p + rowBytes);
}
break;
}
case kRGB_101010x_SkColorType:
a = 255; // then fallthrough to 1010102
case kRGBA_1010102_SkColorType: {
uint32_t* p = this->writable_addr32(area.fLeft, area.fTop);
float R = r * (1/255.0f),
G = g * (1/255.0f),
B = b * (1/255.0f),
A = a * (1/255.0f);
if (a != 255 && this->alphaType() == kPremul_SkAlphaType) {
R *= A;
G *= A;
B *= A;
}
uint32_t v = (uint32_t)(R * 1023.0f) << 0
| (uint32_t)(G * 1023.0f) << 10
| (uint32_t)(B * 1023.0f) << 20
| (uint32_t)(A * 3.0f) << 30;
while (--height >= 0) {
sk_memset32(p, v, width);
p = (uint32_t*)((char*)p + rowBytes);
}
break;
}
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
// The colorspace is unspecified, so assume linear just like getColor().
this->erase(SkColor4f{(1 / 255.0f) * r,
(1 / 255.0f) * g,
(1 / 255.0f) * b,
(1 / 255.0f) * a}, &area);
break;
default:
return false; // no change, so don't call notifyPixelsChanged()
}
return true;
}
bool SkPixmap::erase(const SkColor4f& origColor, const SkIRect* subset) const {
SkPixmap pm;
if (subset) {
if (!this->extractSubset(&pm, *subset)) {
return false;
}
} else {
pm = *this;
}
const SkColor4f color = origColor.pin();
if (pm.colorType() == kRGBA_F16_SkColorType) {
const uint64_t half4 = color.premul().toF16();
for (int y = 0; y < pm.height(); ++y) {
sk_memset64(pm.writable_addr64(0, y), half4, pm.width());
}
return true;
}
if (pm.colorType() == kRGBA_F32_SkColorType) {
const SkPM4f rgba = color.premul();
for (int y = 0; y < pm.height(); ++y) {
auto row = (float*)pm.writable_addr(0, y);
for (int x = 0; x < pm.width(); ++x) {
row[4*x+0] = rgba.r();
row[4*x+1] = rgba.g();
row[4*x+2] = rgba.b();
row[4*x+3] = rgba.a();
}
}
return true;
}
return pm.erase(color.toSkColor());
}
bool SkPixmap::scalePixels(const SkPixmap& actualDst, SkFilterQuality quality) const {
// We may need to tweak how we interpret these just a little below, so we make copies.
SkPixmap src = *this,