Add SkCanvas::writePixels that takes info+pixels directly
add corresponding methods to device (w/ diff name to avoid colliding with exising virtuals) BUG=skia: R=bsalomon@google.com, robertphillips@google.com, junov@google.com, junov@chromium.org Author: reed@google.com Review URL: https://codereview.chromium.org/180113010 git-svn-id: http://skia.googlecode.com/svn/trunk@13697 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a5572e5bb2
commit
4cd9e2169e
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
@ -10,6 +9,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkConfig8888.h"
|
||||
#include "SkString.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
class PremulAndUnpremulAlphaOpsBench : public SkBenchmark {
|
||||
public:
|
||||
@ -45,9 +45,16 @@ protected:
|
||||
bmp2.setConfig(SkBitmap::kARGB_8888_Config, size.width(),
|
||||
size.height());
|
||||
|
||||
SkColorType ct;
|
||||
SkAlphaType at;
|
||||
sk_tool_utils::config8888_to_imagetypes(fUnPremulConfig, &ct, &at);
|
||||
if (bmp1.isOpaque()) {
|
||||
at = kOpaque_SkAlphaType;
|
||||
}
|
||||
|
||||
for (int loop = 0; loop < loops; ++loop) {
|
||||
// Unpremul -> Premul
|
||||
canvas->writePixels(bmp1, 0, 0, fUnPremulConfig);
|
||||
sk_tool_utils::write_pixels(canvas, bmp1, 0, 0, ct, at);
|
||||
// Premul -> Unpremul
|
||||
canvas->readPixels(&bmp2, 0, 0, fUnPremulConfig);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
@ -8,35 +7,35 @@
|
||||
|
||||
#include "SkBenchmark.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkConfig8888.h"
|
||||
#include "SkString.h"
|
||||
|
||||
class WritePixelsBench : public SkBenchmark {
|
||||
public:
|
||||
WritePixelsBench(SkCanvas::Config8888 config)
|
||||
: fConfig(config)
|
||||
, fName("writepix") {
|
||||
switch (config) {
|
||||
case SkCanvas::kNative_Premul_Config8888:
|
||||
fName.append("_native_PM");
|
||||
WritePixelsBench(SkColorType ct, SkAlphaType at)
|
||||
: fColorType(ct)
|
||||
, fAlphaType(at)
|
||||
, fName("writepix")
|
||||
{
|
||||
switch (ct) {
|
||||
case kRGBA_8888_SkColorType:
|
||||
fName.append("_RGBA");
|
||||
break;
|
||||
case SkCanvas::kNative_Unpremul_Config8888:
|
||||
fName.append("_native_UPM");
|
||||
break;
|
||||
case SkCanvas::kBGRA_Premul_Config8888:
|
||||
fName.append("_bgra_PM");
|
||||
break;
|
||||
case SkCanvas::kBGRA_Unpremul_Config8888:
|
||||
fName.append("_bgra_UPM");
|
||||
break;
|
||||
case SkCanvas::kRGBA_Premul_Config8888:
|
||||
fName.append("_rgba_PM");
|
||||
break;
|
||||
case SkCanvas::kRGBA_Unpremul_Config8888:
|
||||
fName.append("_rgba_UPM");
|
||||
case kBGRA_8888_SkColorType:
|
||||
fName.append("_BGRA");
|
||||
break;
|
||||
default:
|
||||
SK_CRASH();
|
||||
SkASSERT(0);
|
||||
break;
|
||||
}
|
||||
switch (at) {
|
||||
case kPremul_SkAlphaType:
|
||||
fName.append("_PM");
|
||||
break;
|
||||
case kUnpremul_SkAlphaType:
|
||||
fName.append("_UPM");
|
||||
break;
|
||||
default:
|
||||
SkASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -52,22 +51,27 @@ protected:
|
||||
canvas->clear(0xFFFF0000);
|
||||
|
||||
SkBitmap bmp;
|
||||
bmp.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
|
||||
bmp.allocN32Pixels(size.width(), size.height());
|
||||
canvas->readPixels(&bmp, 0, 0);
|
||||
|
||||
SkImageInfo info = bmp.info();
|
||||
info.fColorType = fColorType;
|
||||
info.fAlphaType = fAlphaType;
|
||||
|
||||
for (int loop = 0; loop < loops; ++loop) {
|
||||
canvas->writePixels(bmp, 0, 0, fConfig);
|
||||
canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkCanvas::Config8888 fConfig;
|
||||
SkString fName;
|
||||
SkColorType fColorType;
|
||||
SkAlphaType fAlphaType;
|
||||
SkString fName;
|
||||
|
||||
typedef SkBenchmark INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_BENCH( return SkNEW_ARGS(WritePixelsBench, (SkCanvas::kRGBA_Premul_Config8888)); )
|
||||
DEF_BENCH( return SkNEW_ARGS(WritePixelsBench, (SkCanvas::kRGBA_Unpremul_Config8888)); )
|
||||
DEF_BENCH( return SkNEW_ARGS(WritePixelsBench, (kRGBA_8888_SkColorType, kPremul_SkAlphaType)); )
|
||||
DEF_BENCH( return SkNEW_ARGS(WritePixelsBench, (kRGBA_8888_SkColorType, kUnpremul_SkAlphaType)); )
|
||||
|
@ -20,6 +20,7 @@
|
||||
'../bench/SkGMBench.cpp',
|
||||
'../bench/SkGMBench.h',
|
||||
'../bench/benchmain.cpp',
|
||||
'../tools/sk_tool_utils.cpp',
|
||||
],
|
||||
'conditions': [
|
||||
['skia_gpu == 1',
|
||||
@ -54,6 +55,7 @@
|
||||
'include_dirs': [
|
||||
'../src/core',
|
||||
'../src/gpu',
|
||||
'../tools',
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_lib.gyp:skia_lib',
|
||||
|
@ -3,6 +3,7 @@
|
||||
'../src/core',
|
||||
'../src/effects',
|
||||
'../src/utils',
|
||||
'../tools',
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_lib.gyp:skia_lib',
|
||||
|
@ -16,6 +16,7 @@
|
||||
'SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1',
|
||||
'SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1',
|
||||
'SK_SUPPORT_LEGACY_COPYTO_CONFIG',
|
||||
'SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -179,5 +179,7 @@
|
||||
|
||||
'../tests/TDStackNesterTest.cpp',
|
||||
'../experimental/PdfViewer/src/SkTDStackNester.h',
|
||||
|
||||
'../tools/sk_tool_utils.cpp',
|
||||
],
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ public:
|
||||
|
||||
virtual SkImageInfo imageInfo() const SK_OVERRIDE;
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
/**
|
||||
* DEPRECATED: This will be made protected once WebKit stops using it.
|
||||
* Instead use Canvas' writePixels method.
|
||||
@ -103,7 +104,7 @@ public:
|
||||
*/
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Return the device's associated gpu render target, or NULL.
|
||||
*/
|
||||
@ -215,9 +216,8 @@ protected:
|
||||
* 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
|
||||
* contained in the device bounds.
|
||||
*/
|
||||
virtual bool onReadPixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
virtual bool onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) SK_OVERRIDE;
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
|
||||
|
||||
/** Called when this device is installed into a Canvas. Balanced by a call
|
||||
to unlockPixels() when the device is removed from a Canvas.
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "SkRegion.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
//#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
|
||||
class SkBounder;
|
||||
class SkBaseDevice;
|
||||
class SkDraw;
|
||||
@ -264,7 +266,9 @@ public:
|
||||
*/
|
||||
bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
/**
|
||||
* DEPRECATED
|
||||
* Similar to draw sprite, this method will copy the pixels in bitmap onto
|
||||
* the canvas, with the top/left corner specified by (x, y). The canvas'
|
||||
* pixel values are completely replaced: there is no blending.
|
||||
@ -279,9 +283,34 @@ public:
|
||||
* Note: If you are recording drawing commands on this canvas to
|
||||
* SkPicture, writePixels() is ignored!
|
||||
*/
|
||||
void writePixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
Config8888 config8888 = kNative_Premul_Config8888);
|
||||
void writePixels(const SkBitmap& bitmap, int x, int y, Config8888 config8888);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method affects the pixels in the base-layer, and operates in pixel coordinates,
|
||||
* ignoring the matrix and clip.
|
||||
*
|
||||
* The specified ImageInfo and (x,y) offset specifies a rectangle: target.
|
||||
*
|
||||
* target.setXYWH(x, y, info.width(), info.height());
|
||||
*
|
||||
* Target is intersected with the bounds of the base-layer. If this intersection is not empty,
|
||||
* then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
|
||||
* and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
|
||||
* pixels, performing any colortype/alphatype transformations needed (in the case where the
|
||||
* src and dst have different colortypes or alphatypes).
|
||||
*
|
||||
* This call can fail, returning false, for several reasons:
|
||||
* - If the src colortype/alphatype cannot be converted to the canvas' types
|
||||
* - If this canvas is not backed by pixels (e.g. picture or PDF)
|
||||
*/
|
||||
bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
|
||||
|
||||
/**
|
||||
* Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
|
||||
* is just wrapping a texture, returns false and does nothing.
|
||||
*/
|
||||
bool writePixels(const SkBitmap& bitmap, int x, int y);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -116,6 +116,7 @@ public:
|
||||
*/
|
||||
const SkBitmap& accessBitmap(bool changePixels);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
/**
|
||||
* DEPRECATED: This will be made protected once WebKit stops using it.
|
||||
* Instead use Canvas' writePixels method.
|
||||
@ -132,7 +133,10 @@ public:
|
||||
* not kARGB_8888_Config then this parameter is ignored.
|
||||
*/
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0;
|
||||
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
|
||||
#endif
|
||||
|
||||
bool writePixelsDirect(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
|
||||
|
||||
/**
|
||||
* Return the device's associated gpu render target, or NULL.
|
||||
@ -387,6 +391,14 @@ protected:
|
||||
// default impl returns NULL
|
||||
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
|
||||
|
||||
/**
|
||||
* The caller is responsible for "pre-clipping" the src. The impl can assume that the src
|
||||
* image at the specified x,y offset will fit within the device's bounds.
|
||||
*
|
||||
* This is explicitly asserted in writePixelsDirect(), the public way to call this.
|
||||
*/
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
|
||||
|
||||
/**
|
||||
* Leaky properties are those which the device should be applying but it isn't.
|
||||
* These properties will be applied by the draw, when and as it can.
|
||||
|
@ -90,9 +90,10 @@ public:
|
||||
virtual SkBitmap::Config config() const SK_OVERRIDE;
|
||||
|
||||
virtual void clear(SkColor color) SK_OVERRIDE;
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
|
||||
#endif
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
|
||||
@ -148,10 +149,8 @@ public:
|
||||
class SkAutoCachedTexture; // used internally
|
||||
|
||||
protected:
|
||||
// overrides from SkBaseDevice
|
||||
virtual bool onReadPixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
virtual bool onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) SK_OVERRIDE;
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
GrContext* fContext;
|
||||
|
@ -199,6 +199,7 @@ bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap,
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
SkCanvas::Config8888 config8888) {
|
||||
@ -265,6 +266,96 @@ void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
|
||||
draw.fMatrix = &SkMatrix::I();
|
||||
this->drawSprite(draw, *sprite, x, y, paint);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, size_t bytesPerRow,
|
||||
int rowCount) {
|
||||
SkASSERT(bytesPerRow <= srcRB);
|
||||
SkASSERT(bytesPerRow <= dstRB);
|
||||
for (int i = 0; i < rowCount; ++i) {
|
||||
memcpy(dst, src, bytesPerRow);
|
||||
dst = (char*)dst + dstRB;
|
||||
src = (const char*)src + srcRB;
|
||||
}
|
||||
}
|
||||
|
||||
static bool info2config8888(const SkImageInfo& info, SkCanvas::Config8888* config) {
|
||||
bool pre;
|
||||
switch (info.alphaType()) {
|
||||
case kPremul_SkAlphaType:
|
||||
case kOpaque_SkAlphaType:
|
||||
pre = true;
|
||||
break;
|
||||
case kUnpremul_SkAlphaType:
|
||||
pre = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
switch (info.colorType()) {
|
||||
case kRGBA_8888_SkColorType:
|
||||
*config = pre ? SkCanvas::kRGBA_Premul_Config8888 : SkCanvas::kRGBA_Unpremul_Config8888;
|
||||
return true;
|
||||
case kBGRA_8888_SkColorType:
|
||||
*config = pre ? SkCanvas::kBGRA_Premul_Config8888 : SkCanvas::kBGRA_Unpremul_Config8888;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make this guy real, and not rely on legacy config8888 utility
|
||||
#include "SkConfig8888.h"
|
||||
static bool write_pixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
|
||||
const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRowBytes) {
|
||||
if (srcInfo.dimensions() != dstInfo.dimensions()) {
|
||||
return false;
|
||||
}
|
||||
if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) {
|
||||
SkCanvas::Config8888 srcConfig, dstConfig;
|
||||
if (!info2config8888(srcInfo, &srcConfig) || !info2config8888(dstInfo, &dstConfig)) {
|
||||
return false;
|
||||
}
|
||||
SkConvertConfig8888Pixels((uint32_t*)dstPixels, dstRowBytes, dstConfig,
|
||||
(const uint32_t*)srcPixels, srcRowBytes, srcConfig,
|
||||
srcInfo.width(), srcInfo.height());
|
||||
return true;
|
||||
}
|
||||
if (srcInfo.colorType() == dstInfo.colorType()) {
|
||||
switch (srcInfo.colorType()) {
|
||||
case kRGB_565_SkColorType:
|
||||
case kAlpha_8_SkColorType:
|
||||
break;
|
||||
case kARGB_4444_SkColorType:
|
||||
if (srcInfo.alphaType() != dstInfo.alphaType()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
rect_memcpy(dstPixels, dstRowBytes, srcPixels, srcRowBytes,
|
||||
srcInfo.width() * srcInfo.bytesPerPixel(), srcInfo.height());
|
||||
}
|
||||
// TODO: add support for more conversions as needed
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
|
||||
size_t srcRowBytes, int x, int y) {
|
||||
SkImageInfo dstInfo = fBitmap.info();
|
||||
dstInfo.fWidth = srcInfo.width();
|
||||
dstInfo.fHeight = srcInfo.height();
|
||||
|
||||
void* dstPixels = fBitmap.getAddr(x, y);
|
||||
size_t dstRowBytes = fBitmap.rowBytes();
|
||||
|
||||
if (write_pixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) {
|
||||
fBitmap.notifyPixelsChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -696,6 +696,7 @@ bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
Config8888 config8888) {
|
||||
SkBaseDevice* device = this->getDevice();
|
||||
@ -707,6 +708,62 @@ void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
|
||||
if (bitmap.getTexture()) {
|
||||
return false;
|
||||
}
|
||||
SkBitmap bm(bitmap);
|
||||
bm.lockPixels();
|
||||
if (bm.getPixels()) {
|
||||
return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 (NULL == 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;
|
||||
}
|
||||
|
||||
SkImageInfo info = origInfo;
|
||||
// the intersect may have shrunk info's logical size
|
||||
info.fWidth = target.width();
|
||||
info.fHeight = target.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());
|
||||
|
||||
// The device can assert that the requested area is always contained in its bounds
|
||||
return device->writePixelsDirect(info, pixels, rowBytes, target.x(), target.y());
|
||||
}
|
||||
|
||||
SkCanvas* SkCanvas::canvasForDrawIter() {
|
||||
return this;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
@ -6,6 +5,8 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkConfig8888_DEFINED
|
||||
#define SkConfig8888_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorPriv.h"
|
||||
@ -74,3 +75,5 @@ static inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -170,3 +170,27 @@ void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
const bool pathIsMutable = true;
|
||||
this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
bool SkBaseDevice::writePixelsDirect(const SkImageInfo& info, const void* pixels, size_t rowBytes,
|
||||
int x, int y) {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(info.width() > 0 && info.height() > 0);
|
||||
SkASSERT(pixels);
|
||||
SkASSERT(rowBytes >= info.minRowBytes());
|
||||
SkASSERT(x >= 0 && y >= 0);
|
||||
|
||||
const SkImageInfo& dstInfo = this->imageInfo();
|
||||
SkASSERT(x + info.width() <= dstInfo.width());
|
||||
SkASSERT(y + info.height() <= dstInfo.height());
|
||||
#endif
|
||||
return this->onWritePixels(info, pixels, rowBytes, x, y);
|
||||
}
|
||||
|
||||
bool SkBaseDevice::onWritePixels(const SkImageInfo&, const void*, size_t, int, int) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
void SkBaseDevice::writePixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) {}
|
||||
#endif
|
||||
|
||||
|
@ -403,6 +403,7 @@ bool SkGpuDevice::onReadPixels(const SkBitmap& bitmap,
|
||||
flags);
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) {
|
||||
SkAutoLockPixels alp(bitmap);
|
||||
@ -422,6 +423,26 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
fRenderTarget->writePixels(x, y, bitmap.width(), bitmap.height(),
|
||||
config, bitmap.getPixels(), bitmap.rowBytes(), flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
|
||||
int x, int y) {
|
||||
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
|
||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType());
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
uint32_t flags = 0;
|
||||
if (kUnpremul_SkAlphaType == info.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags);
|
||||
|
||||
// need to bump our genID for compatibility with clients that "know" we have a bitmap
|
||||
this->onAccessBitmap().notifyPixelsChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
|
||||
INHERITED::onAttachToCanvas(canvas);
|
||||
|
@ -30,8 +30,7 @@ enum PlaybackMode {
|
||||
kSilent_PlaybackMode,
|
||||
};
|
||||
|
||||
namespace {
|
||||
bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
|
||||
static bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
|
||||
size_t bitmapSizeThreshold) {
|
||||
if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
|
||||
(bitmap->getSize() > bitmapSizeThreshold))) {
|
||||
@ -54,7 +53,6 @@ bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DeferredPipeController
|
||||
@ -170,9 +168,10 @@ public:
|
||||
|
||||
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
|
||||
#endif
|
||||
virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
|
||||
|
||||
protected:
|
||||
@ -180,6 +179,7 @@ protected:
|
||||
virtual bool onReadPixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE;
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y) SK_OVERRIDE;
|
||||
|
||||
// The following methods are no-ops on a deferred device
|
||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
|
||||
@ -478,8 +478,9 @@ void DeferredDevice::prepareForImmediatePixelWrite() {
|
||||
fImmediateCanvas->flush();
|
||||
}
|
||||
|
||||
void DeferredDevice::writePixels(const SkBitmap& bitmap,
|
||||
int x, int y, SkCanvas::Config8888 config8888) {
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
void DeferredDevice::writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) {
|
||||
|
||||
if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
|
||||
(y + bitmap.height()) >= height()) {
|
||||
@ -506,6 +507,24 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool DeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
|
||||
int x, int y) {
|
||||
SkASSERT(x >= 0 && y >= 0);
|
||||
SkASSERT(x + info.width() <= width());
|
||||
SkASSERT(y + info.height() <= height());
|
||||
|
||||
this->flushPendingCommands(kNormal_PlaybackMode);
|
||||
|
||||
const SkImageInfo deviceInfo = this->imageInfo();
|
||||
if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height()) {
|
||||
this->skipPendingCommands();
|
||||
}
|
||||
|
||||
this->prepareForImmediatePixelWrite();
|
||||
return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y);
|
||||
}
|
||||
|
||||
const SkBitmap& DeferredDevice::onAccessBitmap() {
|
||||
this->flushPendingCommands(kNormal_PlaybackMode);
|
||||
|
@ -49,10 +49,12 @@ public:
|
||||
return fEmptyBitmap.info();
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE {
|
||||
NotSupported();
|
||||
}
|
||||
#endif
|
||||
virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
|
||||
|
||||
protected:
|
||||
|
@ -85,10 +85,13 @@ public:
|
||||
virtual void clear(SkColor color) SK_OVERRIDE {
|
||||
nothing_to_do();
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888) SK_OVERRIDE {
|
||||
not_supported();
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE {
|
||||
this->addBitmapFromPaint(paint);
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "SkShader.h"
|
||||
#include "SkSurface.h"
|
||||
#include "Test.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContextFactory.h"
|
||||
#else
|
||||
@ -24,6 +26,21 @@ class GrContextFactory;
|
||||
static const int gWidth = 2;
|
||||
static const int gHeight = 2;
|
||||
|
||||
static void callWritePixels(SkCanvas* canvas, const SkBitmap& src, int x, int y,
|
||||
SkCanvas::Config8888 config) {
|
||||
SkBitmap bm(src);
|
||||
bm.lockPixels();
|
||||
|
||||
SkImageInfo info = bm.info();
|
||||
sk_tool_utils::config8888_to_imagetypes(config, &info.fColorType, &info.fAlphaType);
|
||||
|
||||
if (src.isOpaque()) {
|
||||
info.fAlphaType = kOpaque_SkAlphaType;
|
||||
}
|
||||
|
||||
canvas->writePixels(info, bm.getPixels(), bm.rowBytes(), x, y);
|
||||
}
|
||||
|
||||
static void create(SkBitmap* bm, SkColor color) {
|
||||
bm->allocN32Pixels(gWidth, gHeight);
|
||||
bm->eraseColor(color);
|
||||
@ -145,13 +162,16 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 0, 0);
|
||||
#if 0
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
#endif
|
||||
surface->clearCounts();
|
||||
canvas->flush();
|
||||
#if 0
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
#endif
|
||||
|
||||
// Case 3: writePixels that partially covers the canvas
|
||||
surface->clearCounts();
|
||||
@ -161,13 +181,16 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 5, 0);
|
||||
#if 0
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
#endif
|
||||
surface->clearCounts();
|
||||
canvas->flush();
|
||||
#if 0
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fRetainCount);
|
||||
#endif
|
||||
|
||||
// Case 4: unpremultiplied opaque writePixels that entirely
|
||||
// covers the canvas
|
||||
@ -177,7 +200,7 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
callWritePixels(canvas, srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
@ -194,7 +217,7 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
callWritePixels(canvas, srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fRetainCount);
|
||||
|
||||
@ -216,7 +239,7 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
callWritePixels(canvas, srcBitmap, 0, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
@ -238,7 +261,7 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
callWritePixels(canvas, srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fDiscardCount); // because of the clear
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
@ -262,7 +285,7 @@ static void TestDeferredCanvasWritePixelsToSurface(skiatest::Reporter* reporter)
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fRetainCount);
|
||||
|
||||
surface->clearCounts();
|
||||
canvas->writePixels(srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
callWritePixels(canvas, srcBitmap, 5, 0, SkCanvas::kRGBA_Unpremul_Config8888);
|
||||
REPORTER_ASSERT(reporter, 0 == surface->fDiscardCount);
|
||||
REPORTER_ASSERT(reporter, 1 == surface->fRetainCount);
|
||||
|
||||
|
@ -9,32 +9,62 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkConfig8888.h"
|
||||
#include "Test.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContextFactory.h"
|
||||
#include "SkGpuDevice.h"
|
||||
#endif
|
||||
|
||||
static void fillCanvas(SkCanvas* canvas, SkCanvas::Config8888 unpremulConfig) {
|
||||
SkBitmap bmp;
|
||||
bmp.allocN32Pixels(256, 256);
|
||||
SkAutoLockPixels alp(bmp);
|
||||
uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
|
||||
|
||||
for (int a = 0; a < 256; ++a) {
|
||||
for (int r = 0; r < 256; ++r) {
|
||||
pixels[a * 256 + r] = SkPackConfig8888(unpremulConfig, a, r, 0, 0);
|
||||
}
|
||||
}
|
||||
canvas->writePixels(bmp, 0, 0, unpremulConfig);
|
||||
static uint32_t pack_unpremul_rgba(SkColor c) {
|
||||
uint32_t packed;
|
||||
uint8_t* byte = reinterpret_cast<uint8_t*>(&packed);
|
||||
byte[0] = SkColorGetR(c);
|
||||
byte[1] = SkColorGetG(c);
|
||||
byte[2] = SkColorGetB(c);
|
||||
byte[3] = SkColorGetA(c);
|
||||
return packed;
|
||||
}
|
||||
|
||||
static const SkCanvas::Config8888 gUnpremulConfigs[] = {
|
||||
SkCanvas::kNative_Unpremul_Config8888,
|
||||
SkCanvas::kBGRA_Unpremul_Config8888,
|
||||
SkCanvas::kRGBA_Unpremul_Config8888,
|
||||
static uint32_t pack_unpremul_bgra(SkColor c) {
|
||||
uint32_t packed;
|
||||
uint8_t* byte = reinterpret_cast<uint8_t*>(&packed);
|
||||
byte[0] = SkColorGetB(c);
|
||||
byte[1] = SkColorGetG(c);
|
||||
byte[2] = SkColorGetR(c);
|
||||
byte[3] = SkColorGetA(c);
|
||||
return packed;
|
||||
}
|
||||
|
||||
typedef uint32_t (*PackUnpremulProc)(SkColor);
|
||||
|
||||
const struct {
|
||||
SkColorType fColorType;
|
||||
PackUnpremulProc fPackProc;
|
||||
SkCanvas::Config8888 fConfig8888;
|
||||
} gUnpremul[] = {
|
||||
{ kRGBA_8888_SkColorType, pack_unpremul_rgba, SkCanvas::kRGBA_Unpremul_Config8888 },
|
||||
{ kBGRA_8888_SkColorType, pack_unpremul_bgra, SkCanvas::kBGRA_Unpremul_Config8888 },
|
||||
};
|
||||
|
||||
static void fillCanvas(SkCanvas* canvas, SkColorType colorType, PackUnpremulProc proc) {
|
||||
// Don't strictly need a bitmap, but its a handy way to allocate the pixels
|
||||
SkBitmap bmp;
|
||||
bmp.allocN32Pixels(256, 256);
|
||||
|
||||
for (int a = 0; a < 256; ++a) {
|
||||
uint32_t* pixels = bmp.getAddr32(0, a);
|
||||
for (int r = 0; r < 256; ++r) {
|
||||
pixels[r] = proc(SkColorSetARGB(a, r, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
SkImageInfo info = bmp.info();
|
||||
info.fColorType = colorType;
|
||||
info.fAlphaType = kUnpremul_SkAlphaType;
|
||||
canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
|
||||
}
|
||||
|
||||
DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
|
||||
|
||||
@ -74,32 +104,23 @@ DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
|
||||
SkBitmap readBmp2;
|
||||
readBmp2.allocN32Pixels(256, 256);
|
||||
|
||||
for (size_t upmaIdx = 0;
|
||||
upmaIdx < SK_ARRAY_COUNT(gUnpremulConfigs);
|
||||
++upmaIdx) {
|
||||
fillCanvas(&canvas, gUnpremulConfigs[upmaIdx]);
|
||||
{
|
||||
SkAutoLockPixels alp1(readBmp1);
|
||||
SkAutoLockPixels alp2(readBmp2);
|
||||
sk_bzero(readBmp1.getPixels(), readBmp1.getSafeSize());
|
||||
sk_bzero(readBmp2.getPixels(), readBmp2.getSafeSize());
|
||||
}
|
||||
for (size_t upmaIdx = 0; upmaIdx < SK_ARRAY_COUNT(gUnpremul); ++upmaIdx) {
|
||||
fillCanvas(&canvas, gUnpremul[upmaIdx].fColorType, gUnpremul[upmaIdx].fPackProc);
|
||||
|
||||
readBmp1.eraseColor(0);
|
||||
readBmp2.eraseColor(0);
|
||||
|
||||
canvas.readPixels(&readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
|
||||
canvas.writePixels(readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
|
||||
canvas.readPixels(&readBmp2, 0, 0, gUnpremulConfigs[upmaIdx]);
|
||||
canvas.readPixels(&readBmp1, 0, 0, gUnpremul[upmaIdx].fConfig8888);
|
||||
sk_tool_utils::write_pixels(&canvas, readBmp1, 0, 0, gUnpremul[upmaIdx].fColorType,
|
||||
kUnpremul_SkAlphaType);
|
||||
canvas.readPixels(&readBmp2, 0, 0, gUnpremul[upmaIdx].fConfig8888);
|
||||
|
||||
SkAutoLockPixels alp1(readBmp1);
|
||||
SkAutoLockPixels alp2(readBmp2);
|
||||
uint32_t* pixels1 =
|
||||
reinterpret_cast<uint32_t*>(readBmp1.getPixels());
|
||||
uint32_t* pixels2 =
|
||||
reinterpret_cast<uint32_t*>(readBmp2.getPixels());
|
||||
bool success = true;
|
||||
for (int y = 0; y < 256 && success; ++y) {
|
||||
const uint32_t* pixels1 = readBmp1.getAddr32(0, y);
|
||||
const uint32_t* pixels2 = readBmp2.getAddr32(0, y);
|
||||
for (int x = 0; x < 256 && success; ++x) {
|
||||
int i = y * 256 + x;
|
||||
REPORTER_ASSERT(reporter, success = pixels1[i] == pixels2[i]);
|
||||
REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SkMathPriv.h"
|
||||
#include "SkRegion.h"
|
||||
#include "Test.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContextFactory.h"
|
||||
@ -134,16 +135,13 @@ static uint32_t getBitmapColor(int x, int y, int w, SkCanvas::Config8888 config8
|
||||
}
|
||||
|
||||
static void fillCanvas(SkCanvas* canvas) {
|
||||
static SkBitmap bmp;
|
||||
SkBitmap bmp;
|
||||
if (bmp.isNull()) {
|
||||
SkDEBUGCODE(bool alloc = ) bmp.allocN32Pixels(DEV_W, DEV_H);
|
||||
SkASSERT(alloc);
|
||||
SkAutoLockPixels alp(bmp);
|
||||
intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
|
||||
for (int y = 0; y < DEV_H; ++y) {
|
||||
for (int x = 0; x < DEV_W; ++x) {
|
||||
SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
|
||||
*pixel = getCanvasColor(x, y);
|
||||
*bmp.getAddr32(x, y) = getCanvasColor(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -468,7 +466,12 @@ DEF_GPUTEST(WritePixels, reporter, factory) {
|
||||
SkBitmap bmp;
|
||||
REPORTER_ASSERT(reporter, setupBitmap(&bmp, config8888, rect.width(), rect.height(), SkToBool(tightBmp)));
|
||||
uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
|
||||
canvas.writePixels(bmp, rect.fLeft, rect.fTop, config8888);
|
||||
|
||||
SkColorType ct;
|
||||
SkAlphaType at;
|
||||
sk_tool_utils::config8888_to_imagetypes(config8888, &ct, &at);
|
||||
sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at);
|
||||
|
||||
uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
|
||||
REPORTER_ASSERT(reporter, checkWrite(reporter, &canvas, bmp, rect.fLeft, rect.fTop, config8888));
|
||||
|
||||
|
48
tools/sk_tool_utils.cpp
Normal file
48
tools/sk_tool_utils.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
namespace sk_tool_utils {
|
||||
|
||||
void config8888_to_imagetypes(SkCanvas::Config8888 config, SkColorType* ct, SkAlphaType* at) {
|
||||
switch (config) {
|
||||
case SkCanvas::kNative_Premul_Config8888:
|
||||
*ct = kPMColor_SkColorType;
|
||||
*at = kPremul_SkAlphaType;
|
||||
break;
|
||||
case SkCanvas::kNative_Unpremul_Config8888:
|
||||
*ct = kPMColor_SkColorType;
|
||||
*at = kUnpremul_SkAlphaType;
|
||||
break;
|
||||
case SkCanvas::kBGRA_Premul_Config8888:
|
||||
*ct = kBGRA_8888_SkColorType;
|
||||
*at = kPremul_SkAlphaType;
|
||||
break;
|
||||
case SkCanvas::kBGRA_Unpremul_Config8888:
|
||||
*ct = kBGRA_8888_SkColorType;
|
||||
*at = kUnpremul_SkAlphaType;
|
||||
break;
|
||||
case SkCanvas::kRGBA_Premul_Config8888:
|
||||
*ct = kRGBA_8888_SkColorType;
|
||||
*at = kPremul_SkAlphaType;
|
||||
break;
|
||||
case SkCanvas::kRGBA_Unpremul_Config8888:
|
||||
*ct = kRGBA_8888_SkColorType;
|
||||
*at = kUnpremul_SkAlphaType;
|
||||
break;
|
||||
default:
|
||||
SkASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
void write_pixels(SkCanvas* canvas, const SkBitmap& bitmap, int x, int y,
|
||||
SkColorType colorType, SkAlphaType alphaType) {
|
||||
SkBitmap tmp(bitmap);
|
||||
tmp.lockPixels();
|
||||
|
||||
SkImageInfo info = tmp.info();
|
||||
info.fColorType = colorType;
|
||||
info.fAlphaType = alphaType;
|
||||
|
||||
canvas->writePixels(info, tmp.getPixels(), tmp.rowBytes(), x, y);
|
||||
}
|
||||
|
||||
}
|
28
tools/sk_tool_utils.h
Normal file
28
tools/sk_tool_utils.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef sk_tool_utils_DEFINED
|
||||
#define sk_tool_utils_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkBitmap.h"
|
||||
|
||||
namespace sk_tool_utils {
|
||||
|
||||
/**
|
||||
* Return the colorType and alphaType that correspond to the specified Config8888
|
||||
*/
|
||||
void config8888_to_imagetypes(SkCanvas::Config8888, SkColorType*, SkAlphaType*);
|
||||
|
||||
/**
|
||||
* Call canvas->writePixels() by using the pixels from bitmap, but with an info that claims
|
||||
* the pixels are colorType + alphaType
|
||||
*/
|
||||
void write_pixels(SkCanvas*, const SkBitmap&, int x, int y, SkColorType, SkAlphaType);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user