Make SkGpuDevice know its alpha type
Make SkImage_Gpu snapshots opaque if surface is opaque. BUG=skia:3965 Review URL: https://codereview.chromium.org/1205643002
This commit is contained in:
parent
5fbb623099
commit
74f681dce2
@ -137,7 +137,7 @@ public:
|
||||
|
||||
protected:
|
||||
// Methods made available via GrSurfacePriv
|
||||
SkImageInfo info() const;
|
||||
SkImageInfo info(SkAlphaType) const;
|
||||
bool savePixels(const char* filename);
|
||||
bool hasPendingRead() const;
|
||||
bool hasPendingWrite() const;
|
||||
|
@ -281,7 +281,7 @@ SkBitmap wrap_texture(GrTexture* texture) {
|
||||
SkASSERT(texture);
|
||||
|
||||
SkBitmap result;
|
||||
result.setInfo(texture->surfacePriv().info());
|
||||
result.setInfo(texture->surfacePriv().info(kPremul_SkAlphaType));
|
||||
result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
|
||||
return result;
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ bool GrSurface::readPixels(int left, int top, int width, int height,
|
||||
return false;
|
||||
}
|
||||
|
||||
SkImageInfo GrSurface::info() const {
|
||||
SkImageInfo GrSurface::info(SkAlphaType alphaType) const {
|
||||
SkColorType colorType;
|
||||
SkColorProfileType profileType;
|
||||
if (!GrPixelConfig2ColorAndProfileType(this->config(), &colorType, &profileType)) {
|
||||
sk_throw();
|
||||
}
|
||||
return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType,
|
||||
return SkImageInfo::Make(this->width(), this->height(), colorType, alphaType,
|
||||
profileType);
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,10 @@
|
||||
class GrSurfacePriv {
|
||||
public:
|
||||
/**
|
||||
* Derive a SkImageInfo from the surface's descriptor. This is lossy as ImageInfo has fields not
|
||||
* known to GrSurface (e.g. alphaType).
|
||||
* Derive a SkImageInfo from the surface's descriptor. The caller must provide the alpha type as
|
||||
* GrSurface has no equivalent.
|
||||
*/
|
||||
SkImageInfo info() const { return fSurface->info(); }
|
||||
SkImageInfo info(SkAlphaType alphaType) const { return fSurface->info(alphaType); }
|
||||
|
||||
/**
|
||||
* Write the contents of the surface to a PNG. Returns true if successful.
|
||||
|
@ -122,18 +122,61 @@ public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) {
|
||||
return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags);
|
||||
/** Checks that the alpha type is legal and gets constructor flags. Returns false if device creation
|
||||
should fail. */
|
||||
bool SkGpuDevice::CheckAlphaTypeAndGetFlags(
|
||||
const SkImageInfo* info, SkGpuDevice::InitContents init, unsigned* flags) {
|
||||
*flags = 0;
|
||||
if (info) {
|
||||
switch (info->alphaType()) {
|
||||
case kPremul_SkAlphaType:
|
||||
break;
|
||||
case kOpaque_SkAlphaType:
|
||||
*flags |= SkGpuDevice::kIsOpaque_Flag;
|
||||
break;
|
||||
default: // If it is unpremul or unknown don't try to render
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (kClear_InitContents == init) {
|
||||
*flags |= kNeedClear_Flag;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props,
|
||||
InitContents init) {
|
||||
return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, init);
|
||||
}
|
||||
|
||||
SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height,
|
||||
const SkSurfaceProps* props, unsigned flags) {
|
||||
const SkSurfaceProps* props, InitContents init) {
|
||||
if (!rt || rt->wasDestroyed()) {
|
||||
return NULL;
|
||||
}
|
||||
unsigned flags;
|
||||
if (!CheckAlphaTypeAndGetFlags(NULL, init, &flags)) {
|
||||
return NULL;
|
||||
}
|
||||
return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags));
|
||||
}
|
||||
|
||||
SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
|
||||
const SkImageInfo& info, int sampleCount,
|
||||
const SkSurfaceProps* props, InitContents init) {
|
||||
unsigned flags;
|
||||
if (!CheckAlphaTypeAndGetFlags(&info, init, &flags)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
|
||||
if (NULL == rt) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags));
|
||||
}
|
||||
|
||||
SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
|
||||
const SkSurfaceProps* props, unsigned flags)
|
||||
: INHERITED(SkSurfacePropsCopyOrDefault(props))
|
||||
@ -141,11 +184,13 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
|
||||
fDrawProcs = NULL;
|
||||
|
||||
fContext = SkRef(rt->getContext());
|
||||
fNeedClear = flags & kNeedClear_Flag;
|
||||
fNeedClear = SkToBool(flags & kNeedClear_Flag);
|
||||
fOpaque = SkToBool(flags & kIsOpaque_Flag);
|
||||
|
||||
fRenderTarget = SkRef(rt);
|
||||
|
||||
SkImageInfo info = rt->surfacePriv().info().makeWH(width, height);
|
||||
SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
|
||||
SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height);
|
||||
SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
|
||||
fLegacyBitmap.setInfo(info);
|
||||
fLegacyBitmap.setPixelRef(pr)->unref();
|
||||
@ -192,18 +237,6 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
|
||||
return texture->asRenderTarget();
|
||||
}
|
||||
|
||||
SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
|
||||
const SkImageInfo& info, int sampleCount,
|
||||
const SkSurfaceProps* props, unsigned flags) {
|
||||
|
||||
SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
|
||||
if (NULL == rt) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags));
|
||||
}
|
||||
|
||||
SkGpuDevice::~SkGpuDevice() {
|
||||
if (fDrawProcs) {
|
||||
delete fDrawProcs;
|
||||
@ -229,8 +262,8 @@ bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
|
||||
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
||||
flags = GrContext::kUnpremul_PixelOpsFlag;
|
||||
}
|
||||
return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width(), dstInfo.height(),
|
||||
config, dstPixels, dstRowBytes, flags);
|
||||
return fRenderTarget->readPixels(x, y, dstInfo.width(), dstInfo.height(), config, dstPixels,
|
||||
dstRowBytes, flags);
|
||||
}
|
||||
|
||||
bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
|
||||
@ -331,8 +364,12 @@ void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
|
||||
fRenderTarget->unref();
|
||||
fRenderTarget = newRT.detach();
|
||||
|
||||
SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info());
|
||||
SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info(), fRenderTarget));
|
||||
#ifdef SK_DEBUG
|
||||
SkImageInfo info = fRenderTarget->surfacePriv().info(fOpaque ? kOpaque_SkAlphaType :
|
||||
kPremul_SkAlphaType);
|
||||
SkASSERT(info == fLegacyBitmap.info());
|
||||
#endif
|
||||
SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fLegacyBitmap.info(), fRenderTarget));
|
||||
fLegacyBitmap.setPixelRef(pr)->unref();
|
||||
|
||||
fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext(&this->surfaceProps())));
|
||||
@ -662,8 +699,7 @@ static int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int m
|
||||
|
||||
// Given a bitmap, an optional src rect, and a context with a clip and matrix determine what
|
||||
// pixels from the bitmap are necessary.
|
||||
static void determine_clipped_src_rect(const GrContext* context,
|
||||
const GrRenderTarget* rt,
|
||||
static void determine_clipped_src_rect(const GrRenderTarget* rt,
|
||||
const GrClip& clip,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkBitmap& bitmap,
|
||||
@ -706,7 +742,7 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
|
||||
|
||||
// if it's larger than the max tile size, then we have no choice but tiling.
|
||||
if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
|
||||
determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap,
|
||||
determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap,
|
||||
srcRectPtr, clippedSrcRect);
|
||||
*tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
|
||||
return true;
|
||||
@ -736,7 +772,7 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
|
||||
}
|
||||
|
||||
// Figure out how much of the src we will need based on the src rect and clipping.
|
||||
determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
|
||||
determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
|
||||
clippedSrcRect);
|
||||
*tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
|
||||
size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
|
||||
@ -1672,7 +1708,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
|
||||
|
||||
SkAutoTUnref<GrTexture> texture;
|
||||
// Skia's convention is to only clear a device if it is non-opaque.
|
||||
unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag;
|
||||
InitContents init = cinfo.fInfo.isOpaque() ? kUninit_InitContents : kClear_InitContents;
|
||||
|
||||
// layers are never draw in repeat modes, so we can request an approx
|
||||
// match and ignore any padding.
|
||||
@ -1684,7 +1720,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
|
||||
if (texture) {
|
||||
SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry);
|
||||
return SkGpuDevice::Create(
|
||||
texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, flags);
|
||||
texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, init);
|
||||
} else {
|
||||
SkErrorInternals::SetError( kInternalError_SkError,
|
||||
"---- failed to create gpu device texture [%d %d]\n",
|
||||
|
@ -30,21 +30,22 @@ struct GrCachedLayer;
|
||||
*/
|
||||
class SK_API SkGpuDevice : public SkBaseDevice {
|
||||
public:
|
||||
enum Flags {
|
||||
kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear
|
||||
enum InitContents {
|
||||
kClear_InitContents,
|
||||
kUninit_InitContents
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an SkGpuDevice from a GrRenderTarget.
|
||||
*/
|
||||
static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0);
|
||||
static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, InitContents);
|
||||
|
||||
/**
|
||||
* Creates an SkGpuDevice from a GrRenderTarget whose texture width/height is
|
||||
* different than its actual width/height (e.g., approx-match scratch texture).
|
||||
*/
|
||||
static SkGpuDevice* Create(GrRenderTarget* target, int width, int height,
|
||||
const SkSurfaceProps*, unsigned flags = 0);
|
||||
const SkSurfaceProps*, InitContents);
|
||||
|
||||
/**
|
||||
* New device that will create an offscreen renderTarget based on the ImageInfo and
|
||||
@ -52,7 +53,7 @@ public:
|
||||
* the resource cache budget. On failure, returns NULL.
|
||||
*/
|
||||
static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
|
||||
int sampleCount, const SkSurfaceProps*, unsigned flags = 0);
|
||||
int sampleCount, const SkSurfaceProps*, InitContents);
|
||||
|
||||
virtual ~SkGpuDevice();
|
||||
|
||||
@ -153,6 +154,15 @@ private:
|
||||
// remove when our clients don't rely on accessBitmap()
|
||||
SkBitmap fLegacyBitmap;
|
||||
bool fNeedClear;
|
||||
bool fOpaque;
|
||||
|
||||
enum Flags {
|
||||
kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear
|
||||
kIsOpaque_Flag = 1 << 1, //!< Hint from client that rendering to this device will be
|
||||
// opaque even if the config supports alpha.
|
||||
};
|
||||
static bool CheckAlphaTypeAndGetFlags(const SkImageInfo* info, InitContents init,
|
||||
unsigned* flags);
|
||||
|
||||
SkGpuDevice(GrRenderTarget*, int width, int height, const SkSurfaceProps*, unsigned flags);
|
||||
|
||||
|
@ -61,7 +61,7 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
|
||||
}
|
||||
|
||||
bool SkImage_Gpu::isOpaque() const {
|
||||
return GrPixelConfigIsOpaque(fTexture->config());
|
||||
return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType;
|
||||
}
|
||||
|
||||
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
|
@ -83,7 +83,8 @@ void SkSurface_Gpu::onDiscard() {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props));
|
||||
SkAutoTUnref<SkGpuDevice> device(
|
||||
SkGpuDevice::Create(target, props, SkGpuDevice::kUninit_InitContents));
|
||||
if (!device) {
|
||||
return NULL;
|
||||
}
|
||||
@ -93,7 +94,7 @@ SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurf
|
||||
SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info,
|
||||
int sampleCount, const SkSurfaceProps* props) {
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props,
|
||||
SkGpuDevice::kNeedClear_Flag));
|
||||
SkGpuDevice::kClear_InitContents));
|
||||
if (!device) {
|
||||
return NULL;
|
||||
}
|
||||
@ -113,7 +114,8 @@ SkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextur
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props));
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
if (!device) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1152,7 +1152,8 @@ DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
|
||||
SkSurface::kNo_Budgeted,
|
||||
SkImageInfo::MakeN32Premul(100, 100),
|
||||
0,
|
||||
&props));
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkImageFilter::Proxy proxy(device);
|
||||
|
||||
test_crop_rects(&proxy, reporter);
|
||||
@ -1169,7 +1170,8 @@ DEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) {
|
||||
SkSurface::kNo_Budgeted,
|
||||
SkImageInfo::MakeN32Premul(100, 100),
|
||||
0,
|
||||
&props));
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkCanvas canvas(device);
|
||||
|
||||
test_huge_blur(&canvas, reporter);
|
||||
@ -1186,7 +1188,8 @@ DEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) {
|
||||
SkSurface::kNo_Budgeted,
|
||||
SkImageInfo::MakeN32Premul(1, 1),
|
||||
0,
|
||||
&props));
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkCanvas canvas(device);
|
||||
|
||||
test_xfermode_cropped_input(&canvas, reporter);
|
||||
@ -1203,7 +1206,8 @@ DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) {
|
||||
SkSurface::kNo_Budgeted,
|
||||
SkImageInfo::MakeN32Premul(1, 1),
|
||||
0,
|
||||
&props));
|
||||
&props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkImageFilter::Proxy proxy(device);
|
||||
|
||||
test_negative_blur_sigma(&proxy, reporter);
|
||||
|
@ -90,7 +90,8 @@ DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
|
||||
if (NULL == ctx) {
|
||||
continue;
|
||||
}
|
||||
device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props));
|
||||
device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
|
@ -83,7 +83,8 @@ DEF_GPUTEST(ReadWriteAlpha, reporter, factory) {
|
||||
|
||||
// Now try writing on the single channel texture
|
||||
SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props));
|
||||
SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
SkCanvas canvas(device);
|
||||
|
||||
SkPaint paint;
|
||||
|
@ -30,16 +30,20 @@ enum SurfaceType {
|
||||
kRasterDirect_SurfaceType,
|
||||
kGpu_SurfaceType,
|
||||
kGpuScratch_SurfaceType,
|
||||
|
||||
kLastSurfaceType = kGpuScratch_SurfaceType
|
||||
};
|
||||
static const int kSurfaceTypeCnt = kLastSurfaceType + 1;
|
||||
|
||||
static void release_storage(void* pixels, void* context) {
|
||||
SkASSERT(pixels == context);
|
||||
sk_free(pixels);
|
||||
}
|
||||
|
||||
static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
|
||||
SkImageInfo* requestedInfo = NULL) {
|
||||
static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
|
||||
static SkSurface* create_surface(SurfaceType surfaceType, GrContext* context,
|
||||
SkAlphaType at = kPremul_SkAlphaType,
|
||||
SkImageInfo* requestedInfo = NULL) {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
|
||||
|
||||
if (requestedInfo) {
|
||||
*requestedInfo = info;
|
||||
@ -219,8 +223,8 @@ struct ReleaseDataContext {
|
||||
}
|
||||
};
|
||||
|
||||
static SkImage* createImage(ImageType imageType, GrContext* context, SkColor color,
|
||||
ReleaseDataContext* releaseContext) {
|
||||
static SkImage* create_image(ImageType imageType, GrContext* context, SkColor color,
|
||||
ReleaseDataContext* releaseContext) {
|
||||
const SkPMColor pmcolor = SkPreMultiplyColor(color);
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
|
||||
const size_t rowBytes = info.minRowBytes();
|
||||
@ -347,7 +351,7 @@ static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
|
||||
size_t rowBytes;
|
||||
|
||||
releaseCtx.fData = NULL;
|
||||
SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color, &releaseCtx));
|
||||
SkAutoTUnref<SkImage> image(create_image(gRec[i].fType, ctx, color, &releaseCtx));
|
||||
if (!image.get()) {
|
||||
SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
|
||||
continue; // gpu may not be enabled
|
||||
@ -417,8 +421,8 @@ static void test_canvaspeek(skiatest::Reporter* reporter,
|
||||
SkImageInfo info, requestInfo;
|
||||
size_t rowBytes;
|
||||
|
||||
SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
|
||||
&requestInfo));
|
||||
SkAutoTUnref<SkSurface> surface(create_surface(gRec[i].fType, context,
|
||||
kPremul_SkAlphaType, &requestInfo));
|
||||
surface->getCanvas()->clear(color);
|
||||
|
||||
const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
|
||||
@ -484,8 +488,8 @@ static void test_accessPixels(skiatest::Reporter* reporter, GrContextFactory* fa
|
||||
for (size_t j = 0; j < SK_ARRAY_COUNT(gRec); ++j) {
|
||||
SkImageInfo info, requestInfo;
|
||||
|
||||
SkAutoTUnref<SkSurface> surface(createSurface(gRec[j].fType, context,
|
||||
&requestInfo));
|
||||
SkAutoTUnref<SkSurface> surface(create_surface(gRec[j].fType, context,
|
||||
kPremul_SkAlphaType, &requestInfo));
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
canvas->clear(0);
|
||||
|
||||
@ -501,10 +505,35 @@ static void test_accessPixels(skiatest::Reporter* reporter, GrContextFactory* fa
|
||||
}
|
||||
}
|
||||
|
||||
static void test_snap_alphatype(skiatest::Reporter* reporter, GrContextFactory* factory) {
|
||||
GrContext* context = NULL;
|
||||
#if SK_SUPPORT_GPU
|
||||
context = factory->get(GrContextFactory::kNative_GLContextType);
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
for (int opaque = 0; opaque < 2; ++opaque) {
|
||||
SkAlphaType atype = SkToBool(opaque) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
|
||||
for (int st = 0; st < kSurfaceTypeCnt; ++st) {
|
||||
SurfaceType stype = (SurfaceType)st;
|
||||
SkAutoTUnref<SkSurface> surface(create_surface(stype, context, atype));
|
||||
REPORTER_ASSERT(reporter, surface);
|
||||
if (surface) {
|
||||
SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
|
||||
REPORTER_ASSERT(reporter, image);
|
||||
if (image) {
|
||||
REPORTER_ASSERT(reporter, image->isOpaque() == SkToBool(opaque));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
|
||||
GrContext* context) {
|
||||
// Verify that the right canvas commands trigger a copy on write
|
||||
SkSurface* surface = createSurface(surfaceType, context);
|
||||
SkSurface* surface = create_surface(surfaceType, context);
|
||||
SkAutoTUnref<SkSurface> aur_surface(surface);
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
|
||||
@ -587,7 +616,7 @@ static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter
|
||||
// This test succeeds by not triggering an assertion.
|
||||
// The test verifies that the surface remains writable (usable) after
|
||||
// acquiring and releasing a snapshot without triggering a copy on write.
|
||||
SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
|
||||
SkAutoTUnref<SkSurface> surface(create_surface(surfaceType, context));
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
canvas->clear(1);
|
||||
surface->newImageSnapshot()->unref(); // Create and destroy SkImage
|
||||
@ -602,8 +631,8 @@ static void Test_crbug263329(skiatest::Reporter* reporter,
|
||||
// Bug was caused by onCopyOnWrite releasing the old surface texture
|
||||
// back to the scratch texture pool even though the texture is used
|
||||
// by and active SkImage_Gpu.
|
||||
SkAutoTUnref<SkSurface> surface1(createSurface(surfaceType, context));
|
||||
SkAutoTUnref<SkSurface> surface2(createSurface(surfaceType, context));
|
||||
SkAutoTUnref<SkSurface> surface1(create_surface(surfaceType, context));
|
||||
SkAutoTUnref<SkSurface> surface2(create_surface(surfaceType, context));
|
||||
SkCanvas* canvas1 = surface1->getCanvas();
|
||||
SkCanvas* canvas2 = surface2->getCanvas();
|
||||
canvas1->clear(1);
|
||||
@ -633,7 +662,7 @@ static void Test_crbug263329(skiatest::Reporter* reporter,
|
||||
static void TestGetTexture(skiatest::Reporter* reporter,
|
||||
SurfaceType surfaceType,
|
||||
GrContext* context) {
|
||||
SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context));
|
||||
SkAutoTUnref<SkSurface> surface(create_surface(surfaceType, context));
|
||||
SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
|
||||
GrTexture* texture = as_IB(image)->getTexture();
|
||||
if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) {
|
||||
@ -700,13 +729,13 @@ static void TestSurfaceNoCanvas(skiatest::Reporter* reporter,
|
||||
// are made before a canvas is created.
|
||||
{
|
||||
// Test passes by not asserting
|
||||
SkSurface* surface = createSurface(surfaceType, context);
|
||||
SkSurface* surface = create_surface(surfaceType, context);
|
||||
SkAutoTUnref<SkSurface> aur_surface(surface);
|
||||
surface->notifyContentWillChange(mode);
|
||||
SkDEBUGCODE(surface->validate();)
|
||||
}
|
||||
{
|
||||
SkSurface* surface = createSurface(surfaceType, context);
|
||||
SkSurface* surface = create_surface(surfaceType, context);
|
||||
SkAutoTUnref<SkSurface> aur_surface(surface);
|
||||
SkImage* image1 = surface->newImageSnapshot();
|
||||
SkAutoTUnref<SkImage> aur_image1(image1);
|
||||
@ -740,6 +769,8 @@ DEF_GPUTEST(Surface, reporter, factory) {
|
||||
|
||||
test_accessPixels(reporter, factory);
|
||||
|
||||
test_snap_alphatype(reporter, factory);
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
TestGetTexture(reporter, kRaster_SurfaceType, NULL);
|
||||
if (factory) {
|
||||
|
@ -159,7 +159,9 @@ SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
|
||||
|
||||
uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
|
||||
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target->asRenderTarget(), &props));
|
||||
SkAutoTUnref<SkGpuDevice> device(
|
||||
SkGpuDevice::Create(target->asRenderTarget(), &props,
|
||||
SkGpuDevice::kUninit_InitContents));
|
||||
if (!device) {
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user