aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--debugger/QT/SkGLWidget.cpp6
-rw-r--r--dm/DMGpuSupport.h2
-rwxr-xr-xgm/dftext.cpp5
-rw-r--r--gm/image.cpp2
-rw-r--r--gm/surface.cpp109
-rw-r--r--gm/xfermodes3.cpp3
-rw-r--r--gyp/gmslides.gypi1
-rw-r--r--include/core/SkBitmapDevice.h2
-rw-r--r--include/core/SkCanvas.h21
-rw-r--r--include/core/SkDevice.h4
-rw-r--r--include/core/SkSurface.h89
-rw-r--r--include/core/SkSurfaceProps.h80
-rw-r--r--include/pdf/SkPDFDevice.h2
-rw-r--r--include/utils/SkNoSaveLayerCanvas.h3
-rw-r--r--src/core/SkBitmapDevice.cpp4
-rw-r--r--src/core/SkCanvas.cpp84
-rw-r--r--src/core/SkDevice.cpp8
-rw-r--r--src/core/SkDeviceProperties.h107
-rw-r--r--src/core/SkPaint.cpp38
-rw-r--r--src/core/SkPictureRecord.cpp2
-rw-r--r--src/core/SkPictureRecord.h2
-rw-r--r--src/core/SkRecorder.h2
-rw-r--r--src/core/SkSurfacePriv.h25
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp9
-rw-r--r--src/gpu/GrLayerHoister.cpp6
-rw-r--r--src/gpu/SkGpuDevice.cpp18
-rw-r--r--src/gpu/SkGpuDevice.h9
-rw-r--r--src/image/SkSurface.cpp105
-rw-r--r--src/image/SkSurface_Base.h7
-rw-r--r--src/image/SkSurface_Gpu.cpp31
-rw-r--r--src/image/SkSurface_Raster.cpp29
-rw-r--r--src/pdf/SkPDFDevice.cpp4
-rw-r--r--src/ports/SkImageDecoder_CG.cpp1
-rw-r--r--src/utils/SkDeferredCanvas.cpp6
-rw-r--r--tests/DeferredCanvasTest.cpp8
-rw-r--r--tests/GpuDrawPathTest.cpp3
-rw-r--r--tests/ImageFilterTest.cpp6
-rw-r--r--tests/PremulAlphaRoundTripTest.cpp3
-rw-r--r--tests/ReadWriteAlphaTest.cpp3
-rw-r--r--tests/ResourceCacheTest.cpp2
-rw-r--r--tests/SurfaceTest.cpp2
-rw-r--r--tools/PictureRenderer.cpp3
42 files changed, 607 insertions, 249 deletions
diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp
index dece6419ab..bd24d4e3cb 100644
--- a/debugger/QT/SkGLWidget.cpp
+++ b/debugger/QT/SkGLWidget.cpp
@@ -47,7 +47,8 @@ void SkGLWidget::initializeGL() {
GrBackendRenderTargetDesc desc = this->getDesc(this->width(), this->height());
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
GrRenderTarget* curRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
- fGpuDevice = SkGpuDevice::Create(curRenderTarget);
+ fGpuDevice = SkGpuDevice::Create(curRenderTarget,
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
fCanvas = new SkCanvas(fGpuDevice);
curRenderTarget->unref();
}
@@ -65,7 +66,8 @@ void SkGLWidget::resizeGL(int w, int h) {
GrRenderTarget* curRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
SkSafeUnref(fGpuDevice);
SkSafeUnref(fCanvas);
- fGpuDevice = SkGpuDevice::Create(curRenderTarget);
+ fGpuDevice = SkGpuDevice::Create(curRenderTarget,
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
fCanvas = new SkCanvas(fGpuDevice);
}
fDebugger->setWindowSize(w, h);
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index a3c487d596..af6270dfc3 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -22,7 +22,7 @@ static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
GrGLStandard gpuAPI,
SkImageInfo info,
int samples) {
- return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), info, samples);
+ return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), info, samples, NULL);
}
} // namespace DM
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
index 65e64a9093..dccc62adb4 100755
--- a/gm/dftext.cpp
+++ b/gm/dftext.cpp
@@ -48,8 +48,9 @@ protected:
#if SK_SUPPORT_GPU
GrContext* ctx = inputCanvas->getGrContext();
SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
- SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0,
- SkSurface::kDistanceField_TextRenderMode));
+ SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag,
+ SkSurfaceProps::kLegacyFontHost_InitType);
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0, &props));
SkCanvas* canvas = surface->getCanvas();
#else
SkCanvas* canvas = inputCanvas;
diff --git a/gm/image.cpp b/gm/image.cpp
index 1c2b4a7e55..a0959b2fdd 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -179,7 +179,7 @@ protected:
#if SK_SUPPORT_GPU
GrContext* ctx = canvas->getGrContext();
- SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info, 0));
+ SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info));
#endif
test_surface(canvas, surf0, true);
diff --git a/gm/surface.cpp b/gm/surface.cpp
new file mode 100644
index 0000000000..dbcced2cbf
--- /dev/null
+++ b/gm/surface.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkGradientShader.h"
+#include "SkSurface.h"
+#include "SkSurfaceProps.h"
+
+#define W 200
+#define H 100
+
+static SkShader* make_shader() {
+ int a = 0x99;
+ int b = 0xBB;
+ SkPoint pts[] = { { 0, 0 }, { W, H } };
+ SkColor colors[] = { SkColorSetRGB(a, a, a), SkColorSetRGB(b, b, b) };
+ return SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
+}
+
+static SkSurface* make_surface(GrContext* ctx, const SkImageInfo& info, SkPixelGeometry geo,
+ int disallowAA, int disallowDither) {
+ uint32_t flags = 0;
+ if (disallowAA) {
+ flags |= SkSurfaceProps::kDisallowAntiAlias_Flag;
+ }
+ if (disallowDither) {
+ flags |= SkSurfaceProps::kDisallowDither_Flag;
+ }
+
+ SkSurfaceProps props(flags, geo);
+ if (ctx) {
+ return SkSurface::NewRenderTarget(ctx, info, 0, &props);
+ } else {
+ return SkSurface::NewRaster(info, &props);
+ }
+}
+
+static void test_draw(SkCanvas* canvas, const char label[]) {
+ SkPaint paint;
+
+ paint.setAntiAlias(true);
+ paint.setLCDRenderText(true);
+ paint.setDither(true);
+
+ paint.setShader(make_shader())->unref();
+ canvas->drawRect(SkRect::MakeWH(W, H), paint);
+ paint.setShader(NULL);
+
+ paint.setColor(SK_ColorWHITE);
+ paint.setTextSize(32);
+ paint.setTextAlign(SkPaint::kCenter_Align);
+ canvas->drawText(label, strlen(label), W / 2, H * 3 / 4, paint);
+}
+
+class SurfacePropsGM : public skiagm::GM {
+public:
+ SurfacePropsGM() {}
+
+protected:
+ SkString onShortName() SK_OVERRIDE {
+ return SkString("surfaceprops");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(W * 4, H * 5);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ GrContext* ctx = canvas->getGrContext();
+
+ // must be opaque to have a hope of testing LCD text
+ const SkImageInfo info = SkImageInfo::MakeN32(W, H, kOpaque_SkAlphaType);
+
+ const struct {
+ SkPixelGeometry fGeo;
+ const char* fLabel;
+ } rec[] = {
+ { kUnknown_SkPixelGeometry, "Unknown" },
+ { kRGB_H_SkPixelGeometry, "RGB_H" },
+ { kBGR_H_SkPixelGeometry, "BGR_H" },
+ { kRGB_V_SkPixelGeometry, "RGB_V" },
+ { kBGR_V_SkPixelGeometry, "BGR_V" },
+ };
+
+ SkScalar x = 0;
+ for (int disallowAA = 0; disallowAA <= 1; ++disallowAA) {
+ for (int disallowDither = 0; disallowDither <= 1; ++disallowDither) {
+ SkScalar y = 0;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
+ SkAutoTUnref<SkSurface> surface(make_surface(ctx, info, rec[i].fGeo,
+ disallowAA, disallowDither));
+ test_draw(surface->getCanvas(), rec[i].fLabel);
+ surface->draw(canvas, x, y, NULL);
+ y += H;
+ }
+ x += W;
+ }
+ }
+ }
+
+private:
+ typedef GM INHERITED;
+};
+
+DEF_GM( return new SurfacePropsGM )
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index 74ca643b23..1ca740893b 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -132,7 +132,8 @@ private:
desc.fConfig = SkImageInfo2GrPixelConfig(baseCanvas->imageInfo());
desc.fFlags = kRenderTarget_GrTextureFlagBit;
SkAutoTUnref<GrSurface> surface(context->createUncachedTexture(desc, NULL, 0));
- SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get()));
+ SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get(),
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
if (device.get()) {
tempCanvas = SkNEW_ARGS(SkCanvas, (device.get()));
}
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index fe9c5d959a..04301f4cf9 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -171,6 +171,7 @@
'../gm/strokerects.cpp',
'../gm/strokes.cpp',
'../gm/stroketext.cpp',
+ '../gm/surface.cpp',
'../gm/tablecolorfilter.cpp',
'../gm/texteffects.cpp',
'../gm/testimagefilters.cpp',
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index 39bbab63e5..0ab0234772 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -155,7 +155,7 @@ private:
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
- virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE;
virtual SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 5088d7ded5..77038c3067 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -16,6 +16,7 @@
#include "SkRefCnt.h"
#include "SkPath.h"
#include "SkRegion.h"
+#include "SkSurfaceProps.h"
#include "SkXfermode.h"
#ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL
@@ -200,8 +201,12 @@ public:
* Create a new surface matching the specified info, one that attempts to
* be maximally compatible when used with this canvas. If there is no matching Surface type,
* NULL is returned.
+ *
+ * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
+ * inherits the properties of the surface that owns this canvas. If this canvas has no parent
+ * surface, then the new surface is created with default properties.
*/
- SkSurface* newSurface(const SkImageInfo&);
+ SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL);
/**
* Return the GPU context of the device that is associated with the canvas.
@@ -1192,7 +1197,7 @@ public:
protected:
// default impl defers to getDevice()->newSurface(info)
- virtual SkSurface* onNewSurface(const SkImageInfo&);
+ virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
// default impl defers to its device
virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
@@ -1282,6 +1287,8 @@ private:
// the first N recs that can fit here mean we won't call malloc
uint32_t fMCRecStorage[32];
+ const SkSurfaceProps fProps;
+
int fSaveLayerCount; // number of successful saveLayer calls
int fCullCount; // number of active culls
@@ -1311,14 +1318,20 @@ private:
kDefault_InitFlags = 0,
kConservativeRasterClip_InitFlag = 1 << 0,
};
- SkCanvas(int width, int height, InitFlags flags);
- SkCanvas(SkBaseDevice*, InitFlags flags);
+ SkCanvas(int width, int height, InitFlags);
+ SkCanvas(SkBaseDevice*, const SkSurfaceProps*, InitFlags);
+ SkCanvas(const SkBitmap&, const SkSurfaceProps&);
// needs gettotalclip()
friend SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas*);
SkBaseDevice* createLayerDevice(const SkImageInfo&);
+ // call this each time we attach ourselves to a device
+ // - constructor
+ // - internalSaveLayer
+ void setupDevice(SkBaseDevice*);
+
SkBaseDevice* init(SkBaseDevice*, InitFlags);
/**
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index e74e95f2f3..08320bf7b4 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -288,7 +288,7 @@ protected:
protected:
// default impl returns NULL
- virtual SkSurface* newSurface(const SkImageInfo&);
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&);
// default impl returns NULL
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
@@ -343,6 +343,8 @@ protected:
virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
const SkPaint*);
+ void setPixelGeometry(SkPixelGeometry geo);
+
private:
friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 1871c676f2..e0e60ab7fb 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -10,6 +10,9 @@
#include "SkRefCnt.h"
#include "SkImage.h"
+#include "SkSurfaceProps.h"
+
+//#define SK_SUPPORT_LEGACY_TEXTRENDERMODE
class SkCanvas;
class SkPaint;
@@ -35,7 +38,8 @@ public:
* If the requested surface cannot be created, or the request is not a
* supported configuration, NULL will be returned.
*/
- static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
+ static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
+ const SkSurfaceProps* = NULL);
/**
* The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
@@ -43,7 +47,7 @@ public:
*/
static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
void (*releaseProc)(void* pixels, void* context),
- void* context);
+ void* context, const SkSurfaceProps* = NULL);
/**
* Return a new surface, with the memory for the pixels automatically
@@ -52,45 +56,36 @@ public:
* If the requested surface cannot be created, or the request is not a
* supported configuration, NULL will be returned.
*/
- static SkSurface* NewRaster(const SkImageInfo&);
+ static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL);
/**
* Helper version of NewRaster. It creates a SkImageInfo with the
* specified width and height, and populates the rest of info to match
* pixels in SkPMColor format.
*/
- static SkSurface* NewRasterPMColor(int width, int height) {
- return NewRaster(SkImageInfo::MakeN32Premul(width, height));
+ static SkSurface* NewRasterPMColor(int width, int height, const SkSurfaceProps* props = NULL) {
+ return NewRaster(SkImageInfo::MakeN32Premul(width, height), props);
}
/**
- * Text rendering modes that can be passed to NewRenderTarget*
- */
- enum TextRenderMode {
- /**
- * This will use the standard text rendering method
- */
- kStandard_TextRenderMode,
- /**
- * This will use signed distance fields for text rendering when possible
- */
- kDistanceField_TextRenderMode,
- };
-
- /**
* Return a new surface using the specified render target.
- * The pixels in the rendertarget are not cleared or otherwised changed when the surface
- * is created.
*/
- static SkSurface* NewRenderTargetDirect(GrRenderTarget*,
- TextRenderMode trm = kStandard_TextRenderMode);
-
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*);
+
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
+ return NewRenderTargetDirect(target, NULL);
+ }
+
/**
* Return a new surface whose contents will be drawn to an offscreen
* render target, allocated by the surface.
*/
- static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
- TextRenderMode trm = kStandard_TextRenderMode);
+ static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ const SkSurfaceProps* = NULL);
+
+ static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) {
+ return NewRenderTarget(gr, info, 0, NULL);
+ }
/**
* Return a new surface whose contents will be drawn to an offscreen
@@ -104,8 +99,33 @@ public:
* Note: Scratch textures count against the GrContext's cached resource
* budget.
*/
- static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
- TextRenderMode trm = kStandard_TextRenderMode);
+ static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ const SkSurfaceProps*);
+
+ static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) {
+ return NewScratchRenderTarget(gr, info, 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
+ /**
+ * Text rendering modes that can be passed to NewRenderTarget*
+ */
+ enum TextRenderMode {
+ /**
+ * This will use the standard text rendering method
+ */
+ kStandard_TextRenderMode,
+ /**
+ * This will use signed distance fields for text rendering when possible
+ */
+ kDistanceField_TextRenderMode,
+ };
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget*, TextRenderMode);
+ static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ TextRenderMode);
+ static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ TextRenderMode);
+#endif
int width() const { return fWidth; }
int height() const { return fHeight; }
@@ -194,9 +214,11 @@ public:
*/
const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
+ const SkSurfaceProps& props() const { return fProps; }
+
protected:
- SkSurface(int width, int height);
- SkSurface(const SkImageInfo&);
+ SkSurface(int width, int height, const SkSurfaceProps*);
+ SkSurface(const SkImageInfo&, const SkSurfaceProps*);
// called by subclass if their contents have changed
void dirtyGenerationID() {
@@ -204,9 +226,10 @@ protected:
}
private:
- const int fWidth;
- const int fHeight;
- uint32_t fGenerationID;
+ const SkSurfaceProps fProps;
+ const int fWidth;
+ const int fHeight;
+ uint32_t fGenerationID;
typedef SkRefCnt INHERITED;
};
diff --git a/include/core/SkSurfaceProps.h b/include/core/SkSurfaceProps.h
new file mode 100644
index 0000000000..0154473914
--- /dev/null
+++ b/include/core/SkSurfaceProps.h
@@ -0,0 +1,80 @@
+/*
+ * 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 SkSurfaceProps_DEFINED
+#define SkSurfaceProps_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Description of how the LCD strips are arranged for each pixel. If this is unknown, or the
+ * pixels are meant to be "portable" and/or transformed before showing (e.g. rotated, scaled)
+ * then use kUnknown_SkPixelGeometry.
+ */
+enum SkPixelGeometry {
+ kUnknown_SkPixelGeometry,
+ kRGB_H_SkPixelGeometry,
+ kBGR_H_SkPixelGeometry,
+ kRGB_V_SkPixelGeometry,
+ kBGR_V_SkPixelGeometry,
+};
+
+// Returns true iff geo is a known geometry and is RGB.
+static inline bool SkPixelGeometryIsRGB(SkPixelGeometry geo) {
+ return kRGB_H_SkPixelGeometry == geo || kRGB_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is BGR.
+static inline bool SkPixelGeometryIsBGR(SkPixelGeometry geo) {
+ return kBGR_H_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is horizontal.
+static inline bool SkPixelGeometryIsH(SkPixelGeometry geo) {
+ return kRGB_H_SkPixelGeometry == geo || kBGR_H_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is vertical.
+static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) {
+ return kRGB_V_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+/**
+ * Describes properties and constraints of a given SkSurface. The rendering engine can parse these
+ * during drawing, and can sometimes optimize its performance (e.g. disabling an expensive
+ * feature).
+ */
+class SkSurfaceProps {
+public:
+ enum Flags {
+ kDisallowAntiAlias_Flag = 1 << 0,
+ kDisallowDither_Flag = 1 << 1,
+ kUseDistanceFieldFonts_Flag = 1 << 2,
+ };
+ SkSurfaceProps(uint32_t flags, SkPixelGeometry);
+
+ enum InitType {
+ kLegacyFontHost_InitType
+ };
+ SkSurfaceProps(InitType);
+ SkSurfaceProps(uint32_t flags, InitType);
+
+ uint32_t flags() const { return fFlags; }
+ SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
+
+ bool isDisallowAA() const { return SkToBool(fFlags & kDisallowAntiAlias_Flag); }
+ bool isDisallowDither() const { return SkToBool(fFlags & kDisallowDither_Flag); }
+ bool isUseDistanceFieldFonts() const { return SkToBool(fFlags & kUseDistanceFieldFonts_Flag); }
+
+private:
+ SkSurfaceProps();
+
+ uint32_t fFlags;
+ SkPixelGeometry fPixelGeometry;
+};
+
+#endif
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index bcdcfb24e4..0bfbc36d1a 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -217,7 +217,7 @@ protected:
return false;
}
- virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
private:
// TODO(vandebo): push most of SkPDFDevice's state into a core object in
diff --git a/include/utils/SkNoSaveLayerCanvas.h b/include/utils/SkNoSaveLayerCanvas.h
index 56a09622a0..b6926973e0 100644
--- a/include/utils/SkNoSaveLayerCanvas.h
+++ b/include/utils/SkNoSaveLayerCanvas.h
@@ -16,7 +16,8 @@
// It also simplifies the clipping calls to only use rectangles.
class SK_API SkNoSaveLayerCanvas : public SkCanvas {
public:
- SkNoSaveLayerCanvas(SkBaseDevice* device) : INHERITED(device, kConservativeRasterClip_InitFlag)
+ SkNoSaveLayerCanvas(SkBaseDevice* device)
+ : INHERITED(device, NULL, kConservativeRasterClip_InitFlag)
{}
protected:
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 0d6c4fcd76..b48432efa0 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -357,8 +357,8 @@ void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
draw.drawSprite(src, x, y, paint);
}
-SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info) {
- return SkSurface::NewRaster(info);
+SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+ return SkSurface::NewRaster(info, &props);
}
const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) {
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 6beb26e4ca..dcc7047dbc 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-
#include "SkCanvas.h"
#include "SkCanvasPriv.h"
#include "SkBitmapDevice.h"
@@ -67,6 +66,19 @@ void SkCanvas::predrawNotify() {
///////////////////////////////////////////////////////////////////////////////
+static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) {
+ const uint32_t propFlags = props.flags();
+ if (propFlags & SkSurfaceProps::kDisallowDither_Flag) {
+ flags &= ~SkPaint::kDither_Flag;
+ }
+ if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) {
+ flags &= ~SkPaint::kAntiAlias_Flag;
+ }
+ return flags;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
/* This is the record we keep for each SkBaseDevice that the user installs.
The clip/matrix/proc are fields that reflect the top of the save/restore
stack. Whenever the canvas changes, it marks a dirty flag, and then before
@@ -250,12 +262,12 @@ private:
class AutoDrawLooper {
public:
- AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint,
+ AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint,
bool skipLayerForImageFilter = false,
const SkRect* bounds = NULL) : fOrigPaint(paint) {
fCanvas = canvas;
fFilter = canvas->getDrawFilter();
- fPaint = NULL;
+ fPaint = &fOrigPaint;
fSaveCount = canvas->getSaveCount();
fDoClearImageFilter = false;
fDone = false;
@@ -280,6 +292,15 @@ public:
// can we be marked as simple?
fIsSimple = !fFilter && !fDoClearImageFilter;
}
+
+ uint32_t oldFlags = paint.getFlags();
+ fNewPaintFlags = filter_paint_flags(props, oldFlags);
+ if (fIsSimple && (fNewPaintFlags != oldFlags)) {
+ SkPaint* paint = fLazyPaint.set(fOrigPaint);
+ paint->setFlags(fNewPaintFlags);
+ fPaint = paint;
+ // if we're not simple, doNext() will take care of calling setFlags()
+ }
}
~AutoDrawLooper() {
@@ -299,7 +320,6 @@ public:
return false;
} else if (fIsSimple) {
fDone = true;
- fPaint = &fOrigPaint;
return !fPaint->nothingToDraw();
} else {
return this->doNext(drawType);
@@ -313,6 +333,7 @@ private:
SkDrawFilter* fFilter;
const SkPaint* fPaint;
int fSaveCount;
+ uint32_t fNewPaintFlags;
bool fDoClearImageFilter;
bool fDone;
bool fIsSimple;
@@ -328,6 +349,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
SkASSERT(fLooperContext || fFilter || fDoClearImageFilter);
SkPaint* paint = fLazyPaint.set(fOrigPaint);
+ paint->setFlags(fNewPaintFlags);
if (fDoClearImageFilter) {
paint->setImageFilter(NULL);
@@ -362,19 +384,17 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
return true;
}
-#include "SkColorPriv.h"
-
////////// macros to place around the internal draw calls //////////////////
#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \
this->predrawNotify(); \
- AutoDrawLooper looper(this, paint, true); \
+ AutoDrawLooper looper(this, fProps, paint, true); \
while (looper.next(type)) { \
SkDrawIter iter(this);
#define LOOPER_BEGIN(paint, type, bounds) \
this->predrawNotify(); \
- AutoDrawLooper looper(this, paint, false, bounds); \
+ AutoDrawLooper looper(this, fProps, paint, false, bounds); \
while (looper.next(type)) { \
SkDrawIter iter(this);
@@ -382,6 +402,10 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
////////////////////////////////////////////////////////////////////////////
+void SkCanvas::setupDevice(SkBaseDevice* device) {
+ device->setPixelGeometry(fProps.pixelGeometry());
+}
+
SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag);
fCachedLocalClipBounds.setEmpty();
@@ -393,10 +417,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fCullCount = 0;
fMetaData = NULL;
- if (device && device->forceConservativeRasterClip()) {
- fConservativeRasterClip = true;
- }
-
fMCRec = (MCRec*)fMCStack.push_back();
new (fMCRec) MCRec(fConservativeRasterClip);
@@ -406,6 +426,10 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fSurfaceBase = NULL;
if (device) {
+ this->setupDevice(device);
+ if (device->forceConservativeRasterClip()) {
+ fConservativeRasterClip = true;
+ }
device->onAttachToCanvas(this);
fMCRec->fLayer->fDevice = SkRef(device);
fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height()));
@@ -415,6 +439,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
SkCanvas::SkCanvas()
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
@@ -438,6 +463,7 @@ private:
SkCanvas::SkCanvas(int width, int height)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
@@ -446,14 +472,16 @@ SkCanvas::SkCanvas(int width, int height)
SkCanvas::SkCanvas(int width, int height, InitFlags flags)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
}
-SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
+SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfacePropsCopyOrDefault(props))
{
inc_canvas();
@@ -462,18 +490,31 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
SkCanvas::SkCanvas(SkBaseDevice* device)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(device, kDefault_InitFlags);
}
-SkCanvas::SkCanvas(const SkBitmap& bitmap)
+SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(props)
{
inc_canvas();
+
+ SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
+ this->init(device, kDefault_InitFlags);
+}
- this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref();
+SkCanvas::SkCanvas(const SkBitmap& bitmap)
+ : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
+{
+ inc_canvas();
+
+ SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
+ this->init(device, kDefault_InitFlags);
}
SkCanvas::~SkCanvas() {
@@ -564,6 +605,7 @@ SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) {
SkRefCnt_SafeAssign(rec->fLayer->fDevice, device);
rootDevice = device;
+ this->setupDevice(device);
fDeviceCMDirty = true;
@@ -899,6 +941,7 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Save
SkDebugf("Unable to create device for layer.");
return count;
}
+ this->setupDevice(device);
device->setOrigin(ir.fLeft, ir.fTop);
DeviceCM* layer = SkNEW_ARGS(DeviceCM,
@@ -994,13 +1037,16 @@ bool SkCanvas::isDrawingToLayer() const {
return fSaveLayerCount > 0;
}
-SkSurface* SkCanvas::newSurface(const SkImageInfo& info) {
- return this->onNewSurface(info);
+SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) {
+ if (NULL == props) {
+ props = &fProps;
+ }
+ return this->onNewSurface(info, *props);
}
-SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) {
+SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
SkBaseDevice* dev = this->getDevice();
- return dev ? dev->newSurface(info) : NULL;
+ return dev ? dev->newSurface(info, props) : NULL;
}
SkImageInfo SkCanvas::imageInfo() const {
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 15d0ab6d2c..63a7633648 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -14,7 +14,7 @@
#include "SkTextBlob.h"
SkBaseDevice::SkBaseDevice()
- : fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::MakeDefault())))
+ : fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType)))
#ifdef SK_DEBUG
, fAttachedToCanvas(false)
#endif
@@ -57,7 +57,11 @@ const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
return bitmap;
}
-SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
+void SkBaseDevice::setPixelGeometry(SkPixelGeometry geo) {
+ fLeakyProperties->fPixelGeometry = geo;
+}
+
+SkSurface* SkBaseDevice::newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; }
const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
diff --git a/src/core/SkDeviceProperties.h b/src/core/SkDeviceProperties.h
index 80e0177650..11ecd65157 100644
--- a/src/core/SkDeviceProperties.h
+++ b/src/core/SkDeviceProperties.h
@@ -1,103 +1,26 @@
+/*
+ * 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 SkDeviceProperties_DEFINED
#define SkDeviceProperties_DEFINED
-//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import.
-#include "SkFontLCDConfig.h"
+#include "SkSurfacePriv.h"
struct SkDeviceProperties {
- struct Geometry {
- /** The orientation of the pixel specifies the interpretation of the
- * layout. If the orientation is horizontal, the layout is interpreted as
- * left to right. It the orientation is vertical, the layout is
- * interpreted top to bottom (rotated 90deg cw from horizontal).
- */
- enum Orientation {
- kUnknown_Orientation = 0x0,
- kKnown_Orientation = 0x2,
-
- kHorizontal_Orientation = 0x2, //!< this is the default
- kVertical_Orientation = 0x3,
-
- kOrientationMask = 0x3,
- };
-
- /** The layout of the pixel specifies its subpixel geometry.
- *
- * kUnknown_Layout means that the subpixel elements are not spatially
- * separated in any known or usable fashion.
- */
- enum Layout {
- kUnknown_Layout = 0x0,
- kKnown_Layout = 0x8,
-
- kRGB_Layout = 0x8, //!< this is the default
- kBGR_Layout = 0xC,
-
- kLayoutMask = 0xC,
- };
-
- Orientation getOrientation() {
- return static_cast<Orientation>(fGeometry & kOrientationMask);
- }
- Layout getLayout() {
- return static_cast<Layout>(fGeometry & kLayoutMask);
- }
-
- bool isOrientationKnown() {
- return SkToBool(fGeometry & kKnown_Orientation);
- }
- bool isLayoutKnown() {
- return SkToBool(fGeometry & kKnown_Layout);
- }
-
- private:
- //TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants.
- static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) {
- switch (orientation) {
- case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation;
- case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation;
- default: return kUnknown_Orientation;
- }
- }
- static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) {
- switch (order) {
- case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout;
- case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout;
- default: return kUnknown_Layout;
- }
- }
- public:
- static Geometry MakeDefault() {
- Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation
- Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout
- Geometry ret = { SkToU8(orientation | layout) };
- return ret;
- }
-
- static Geometry Make(Orientation orientation, Layout layout) {
- Geometry ret = { SkToU8(orientation | layout) };
- return ret;
- }
-
- uint8_t fGeometry;
+ enum InitType {
+ kLegacyLCD_InitType
};
+ SkDeviceProperties(InitType) : fPixelGeometry(SkSurfacePropsDefaultPixelGeometry()) {}
+ SkDeviceProperties(SkPixelGeometry geo) : fPixelGeometry(geo) {}
- static SkDeviceProperties MakeDefault() {
- SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT };
- return ret;
- }
-
- static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) {
- SkDeviceProperties ret = { geometry, gamma };
- return ret;
- }
-
- /** Each pixel of an image will have some number of channels.
- * Can the layout of those channels be exploited? */
- Geometry fGeometry;
+ SkPixelGeometry fPixelGeometry;
- /** Represents the color space of the image. This is a woefully inadequate beginning. */
- SkScalar fGamma;
+ // read-only attribute -- until we actually store a value (future CL)
+ float getGamma() const { return SK_GAMMA_EXPONENT; }
};
#endif
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 88bde22704..42144c1029 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1607,19 +1607,33 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
- SkDeviceProperties::Geometry geometry = deviceProperties
- ? deviceProperties->fGeometry
- : SkDeviceProperties::Geometry::MakeDefault();
if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) {
- if (!geometry.isOrientationKnown() || !geometry.isLayoutKnown() || tooBigForLCD(*rec)) {
- // eeek, can't support LCD
+ if (tooBigForLCD(*rec)) {
rec->fMaskFormat = SkMask::kA8_Format;
+ flags |= SkScalerContext::kGenA8FromLCD_Flag;
} else {
- if (SkDeviceProperties::Geometry::kVertical_Orientation == geometry.getOrientation()) {
- flags |= SkScalerContext::kLCD_Vertical_Flag;
- }
- if (SkDeviceProperties::Geometry::kBGR_Layout == geometry.getLayout()) {
- flags |= SkScalerContext::kLCD_BGROrder_Flag;
+ SkPixelGeometry geometry = deviceProperties
+ ? deviceProperties->fPixelGeometry
+ : SkSurfacePropsDefaultPixelGeometry();
+ switch (geometry) {
+ case kUnknown_SkPixelGeometry:
+ // eeek, can't support LCD
+ rec->fMaskFormat = SkMask::kA8_Format;
+ flags |= SkScalerContext::kGenA8FromLCD_Flag;
+ break;
+ case kRGB_H_SkPixelGeometry:
+ // our default, do nothing.
+ break;
+ case kBGR_H_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_BGROrder_Flag;
+ break;
+ case kRGB_V_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_Vertical_Flag;
+ break;
+ case kBGR_V_SkPixelGeometry:
+ flags |= SkScalerContext::kLCD_Vertical_Flag;
+ flags |= SkScalerContext::kLCD_BGROrder_Flag;
+ break;
}
}
}
@@ -1650,13 +1664,13 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
rec->setDeviceGamma(SK_GAMMA_EXPONENT);
rec->setPaintGamma(SK_GAMMA_EXPONENT);
} else {
- rec->setDeviceGamma(deviceProperties->fGamma);
+ rec->setDeviceGamma(deviceProperties->getGamma());
//For now always set the paint gamma equal to the device gamma.
//The math in SkMaskGamma can handle them being different,
//but it requires superluminous masks when
//Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
- rec->setPaintGamma(deviceProperties->fGamma);
+ rec->setPaintGamma(deviceProperties->getGamma());
}
#ifdef SK_GAMMA_CONTRAST
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index cae8420e95..5b28468898 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -1429,7 +1429,7 @@ void SkPictureRecord::onPopCull() {
///////////////////////////////////////////////////////////////////////////////
-SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) {
+SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
return NULL;
}
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index f2dd87b76a..f8895c950e 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -194,7 +194,7 @@ protected:
SkASSERT(fWriter.bytesWritten() == initialOffset + size);
}
- virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
+ virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE {
return NULL;
}
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index db57eb0702..9eb68319cb 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -115,7 +115,7 @@ public:
void drawData(const void*, size_t) SK_OVERRIDE;
bool isDrawingToLayer() const SK_OVERRIDE;
- SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE { return NULL; }
+ SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE { return NULL; }
private:
template <typename T>
diff --git a/src/core/SkSurfacePriv.h b/src/core/SkSurfacePriv.h
new file mode 100644
index 0000000000..74d19a6df4
--- /dev/null
+++ b/src/core/SkSurfacePriv.h
@@ -0,0 +1,25 @@
+/*
+ * 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 SkSurfacePriv_DEFINED
+#define SkSurfacePriv_DEFINED
+
+#include "SkSurfaceProps.h"
+
+static inline SkSurfaceProps SkSurfacePropsCopyOrDefault(const SkSurfaceProps* props) {
+ if (props) {
+ return *props;
+ } else {
+ return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ }
+}
+
+static inline SkPixelGeometry SkSurfacePropsDefaultPixelGeometry() {
+ return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType).pixelGeometry();
+}
+
+#endif
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 313c02ac51..df07204fcb 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -131,8 +131,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0;
flags |= fUseLCDText && fTextMatrix.rectStaysRect() ?
kRectToRect_DistanceFieldEffectFlag : 0;
- bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
- fDeviceProperties.fGeometry.getLayout();
+ bool useBGR = SkPixelGeometryIsBGR(fDeviceProperties.fPixelGeometry);
flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0;
// see if we need to create a new effect
@@ -149,7 +148,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
flags));
} else {
#ifdef SK_GAMMA_APPLY_TO_A8
- U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma,
+ U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.getGamma(),
filteredColor);
fCachedEffect.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture,
params,
@@ -502,8 +501,8 @@ static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
#else
SkScalar contrast = 0.5f;
#endif
- SkScalar paintGamma = deviceProperties.fGamma;
- SkScalar deviceGamma = deviceProperties.fGamma;
+ SkScalar paintGamma = deviceProperties.getGamma();
+ SkScalar deviceGamma = deviceProperties.getGamma();
size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
&width, &height);
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index ba431d33e9..165716f82d 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -142,8 +142,7 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
if (atlased.count() > 0) {
// All the atlased layers are rendered into the same GrTexture
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
- atlased[0]->texture()->asRenderTarget(),
- SkSurface::kStandard_TextRenderMode));
+ atlased[0]->texture()->asRenderTarget(), NULL));
SkCanvas* atlasCanvas = surface->getCanvas();
@@ -196,8 +195,7 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
// Each non-atlased layer has its own GrTexture
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
- layer->texture()->asRenderTarget(),
- SkSurface::kStandard_TextRenderMode));
+ layer->texture()->asRenderTarget(), NULL));
SkCanvas* layerCanvas = surface->getCanvas();
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 02dca83ee0..7ce3446b72 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -133,15 +133,15 @@ public:
///////////////////////////////////////////////////////////////////////////////
-SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, unsigned flags) {
+SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
SkASSERT(surface);
if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
return NULL;
}
- return SkNEW_ARGS(SkGpuDevice, (surface, flags));
+ return SkNEW_ARGS(SkGpuDevice, (surface, props, flags));
}
-SkGpuDevice::SkGpuDevice(GrSurface* surface, unsigned flags) {
+SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
fDrawProcs = NULL;
@@ -156,13 +156,15 @@ SkGpuDevice::SkGpuDevice(GrSurface* surface, unsigned flags) {
fLegacyBitmap.setInfo(surface->info());
fLegacyBitmap.setPixelRef(pr)->unref();
+ this->setPixelGeometry(props.pixelGeometry());
+
bool useDFFonts = !!(flags & kDFFonts_Flag);
fMainTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFFonts);
fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, this->getLeakyProperties()));
}
SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
- int sampleCount) {
+ const SkSurfaceProps& props, int sampleCount) {
if (kUnknown_SkColorType == origInfo.colorType() ||
origInfo.width() < 0 || origInfo.height() < 0) {
return NULL;
@@ -194,7 +196,7 @@ SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo
return NULL;
}
- return SkNEW_ARGS(SkGpuDevice, (texture.get()));
+ return SkNEW_ARGS(SkGpuDevice, (texture.get(), props));
}
SkGpuDevice::~SkGpuDevice() {
@@ -1805,7 +1807,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage)
texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
#endif
if (texture.get()) {
- return SkGpuDevice::Create(texture, flags);
+ return SkGpuDevice::Create(texture, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), flags);
} else {
GrPrintf("---- failed to create compatible device texture [%d %d]\n",
info.width(), info.height());
@@ -1813,8 +1815,8 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage)
}
}
-SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) {
- return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples());
+SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+ return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props);
}
void SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index dc59009dae..41b53b1213 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -43,7 +43,7 @@ public:
* the kCached_Flag should be specified to make the device responsible for unlocking
* the surface when it is released.
*/
- static SkGpuDevice* Create(GrSurface* surface, unsigned flags = 0);
+ static SkGpuDevice* Create(GrSurface* surface, const SkSurfaceProps&, unsigned flags = 0);
/**
* New device that will create an offscreen renderTarget based on the
@@ -51,7 +51,8 @@ public:
* count against the GrContext's texture cache budget. The device's pixels
* will be uninitialized. On failure, returns NULL.
*/
- static SkGpuDevice* Create(GrContext*, const SkImageInfo&, int sampleCount);
+ static SkGpuDevice* Create(GrContext*, const SkImageInfo&, const SkSurfaceProps&,
+ int sampleCount);
virtual ~SkGpuDevice();
@@ -145,11 +146,11 @@ private:
// remove when our clients don't rely on accessBitmap()
SkBitmap fLegacyBitmap;
- SkGpuDevice(GrSurface*, unsigned flags = 0);
+ SkGpuDevice(GrSurface*, const SkSurfaceProps&, unsigned flags = 0);
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
- virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
virtual SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 3a28e421a8..2d0ce7062f 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -9,14 +9,56 @@
#include "SkImagePriv.h"
#include "SkCanvas.h"
+#include "SkFontLCDConfig.h"
+static SkPixelGeometry compute_default_geometry() {
+ SkFontLCDConfig::LCDOrder order = SkFontLCDConfig::GetSubpixelOrder();
+ if (SkFontLCDConfig::kNONE_LCDOrder == order) {
+ return kUnknown_SkPixelGeometry;
+ } else {
+ // Bit0 is RGB(0), BGR(1)
+ // Bit1 is H(0), V(1)
+ const SkPixelGeometry gGeo[] = {
+ kRGB_H_SkPixelGeometry,
+ kBGR_H_SkPixelGeometry,
+ kRGB_V_SkPixelGeometry,
+ kBGR_V_SkPixelGeometry,
+ };
+ int index = 0;
+ if (SkFontLCDConfig::kBGR_LCDOrder == order) {
+ index |= 1;
+ }
+ if (SkFontLCDConfig::kVertical_LCDOrientation == SkFontLCDConfig::GetSubpixelOrientation()){
+ index |= 2;
+ }
+ return gGeo[index];
+ }
+}
+
+SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
+
+SkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {}
+
+SkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType)
+ : fFlags(flags)
+ , fPixelGeometry(compute_default_geometry())
+{}
+
+SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
+ : fFlags(flags), fPixelGeometry(pg)
+{}
+
///////////////////////////////////////////////////////////////////////////////
-SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
+SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
+ : INHERITED(width, height, props)
+{
fCachedCanvas = NULL;
fCachedImage = NULL;
}
-SkSurface_Base::SkSurface_Base(const SkImageInfo& info) : INHERITED(info) {
+SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
+ : INHERITED(info, props)
+{
fCachedCanvas = NULL;
fCachedImage = NULL;
}
@@ -31,8 +73,7 @@ SkSurface_Base::~SkSurface_Base() {
SkSafeUnref(fCachedCanvas);
}
-void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
- const SkPaint* paint) {
+void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
SkImage* image = this->newImageSnapshot();
if (image) {
image->draw(canvas, x, y, paint);
@@ -74,13 +115,17 @@ static SkSurface_Base* asSB(SkSurface* surface) {
///////////////////////////////////////////////////////////////////////////////
-SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
+SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
+ : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
+{
SkASSERT(fWidth >= 0);
SkASSERT(fHeight >= 0);
fGenerationID = 0;
}
-SkSurface::SkSurface(const SkImageInfo& info) : fWidth(info.width()), fHeight(info.height()) {
+SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
+ : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
+{
SkASSERT(fWidth >= 0);
SkASSERT(fHeight >= 0);
fGenerationID = 0;
@@ -119,3 +164,51 @@ void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
return this->getCanvas()->peekPixels(info, rowBytes);
}
+
+//////////////////////////////////////////////////////////////////////////////////////
+#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
+
+static SkSurfaceProps make_props(SkSurface::TextRenderMode trm) {
+ uint32_t propsFlags = 0;
+ if (SkSurface::kDistanceField_TextRenderMode == trm) {
+ propsFlags |= SkSurfaceProps::kUseDistanceFieldFonts_Flag;
+ }
+ return SkSurfaceProps(propsFlags, SkSurfaceProps::kLegacyFontHost_InitType);
+}
+
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, TextRenderMode trm,
+ RenderTargetFlags flags) {
+ SkSurfaceProps props = make_props(trm);
+ return NewRenderTargetDirect(target, &props, flags);
+}
+
+SkSurface* SkSurface::NewRenderTarget(GrContext* gr, const SkImageInfo& info, int sampleCount,
+ TextRenderMode trm, RenderTargetFlags flags) {
+ SkSurfaceProps props = make_props(trm);
+ return NewRenderTarget(gr, info, sampleCount, &props, flags);
+}
+
+SkSurface* SkSurface::NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info, int sampleCount,
+ TextRenderMode trm, RenderTargetFlags flags) {
+ SkSurfaceProps props = make_props(trm);
+ return NewScratchRenderTarget(gr, info, sampleCount, &props, flags);
+}
+
+#endif
+
+#if !SK_SUPPORT_GPU
+
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*) {
+ return NULL;
+}
+
+SkSurface* SkSurface::NewRenderTarget(GrContext*, const SkImageInfo&, int, const SkSurfaceProps*) {
+ return NULL;
+}
+
+SkSurface* SkSurface::NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ const SkSurfaceProps*) {
+ return NULL;
+}
+
+#endif
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index e7fa57af0d..4da4cfb496 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -8,13 +8,14 @@
#ifndef SkSurface_Base_DEFINED
#define SkSurface_Base_DEFINED
-#include "SkSurface.h"
#include "SkCanvas.h"
+#include "SkSurface.h"
+#include "SkSurfacePriv.h"
class SkSurface_Base : public SkSurface {
public:
- SkSurface_Base(int width, int height);
- explicit SkSurface_Base(const SkImageInfo&);
+ SkSurface_Base(int width, int height, const SkSurfaceProps*);
+ SkSurface_Base(const SkImageInfo&, const SkSurfaceProps*);
virtual ~SkSurface_Base();
/**
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index d7260ac29e..024c151cea 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -14,7 +14,7 @@ class SkSurface_Gpu : public SkSurface_Base {
public:
SK_DECLARE_INST_COUNT(SkSurface_Gpu)
- SkSurface_Gpu(GrRenderTarget*, bool cached, TextRenderMode trm, bool doClear);
+ SkSurface_Gpu(GrRenderTarget*, bool cached, const SkSurfaceProps*, bool doClear);
virtual ~SkSurface_Gpu();
virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
@@ -33,13 +33,14 @@ private:
///////////////////////////////////////////////////////////////////////////////
-SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, bool cached, TextRenderMode trm,
+SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, bool cached, const SkSurfaceProps* props,
bool doClear)
- : INHERITED(renderTarget->width(), renderTarget->height()) {
+ : INHERITED(renderTarget->width(), renderTarget->height(), props)
+{
int deviceFlags = 0;
deviceFlags |= cached ? SkGpuDevice::kCached_Flag : 0;
- deviceFlags |= (kDistanceField_TextRenderMode == trm) ? SkGpuDevice::kDFFonts_Flag : 0;
- fDevice = SkGpuDevice::Create(renderTarget, deviceFlags);
+ deviceFlags |= this->props().isUseDistanceFieldFonts() ? SkGpuDevice::kDFFonts_Flag : 0;
+ fDevice = SkGpuDevice::Create(renderTarget, this->props(), deviceFlags);
if (kRGB_565_GrPixelConfig != renderTarget->config() && doClear) {
fDevice->clear(0x0);
@@ -51,13 +52,17 @@ SkSurface_Gpu::~SkSurface_Gpu() {
}
SkCanvas* SkSurface_Gpu::onNewCanvas() {
- return SkNEW_ARGS(SkCanvas, (fDevice));
+ SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
+ // When we think this works...
+// flags |= SkCanvas::kConservativeRasterClip_InitFlag;
+
+ return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags));
}
SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
GrRenderTarget* rt = fDevice->accessRenderTarget();
int sampleCount = rt->numSamples();
- return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount);
+ return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount, &this->props());
}
SkImage* SkSurface_Gpu::onNewImageSnapshot() {
@@ -102,15 +107,15 @@ void SkSurface_Gpu::onDiscard() {
///////////////////////////////////////////////////////////////////////////////
-SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, TextRenderMode trm) {
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
if (NULL == target) {
return NULL;
}
- return SkNEW_ARGS(SkSurface_Gpu, (target, false, trm, false));
+ return SkNEW_ARGS(SkSurface_Gpu, (target, false, props, false));
}
SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, int sampleCount,
- TextRenderMode trm) {
+ const SkSurfaceProps* props) {
if (NULL == ctx) {
return NULL;
}
@@ -127,11 +132,11 @@ SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, i
return NULL;
}
- return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), false, trm, true));
+ return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), false, props, true));
}
SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo& info,
- int sampleCount, TextRenderMode trm) {
+ int sampleCount, const SkSurfaceProps* props) {
if (NULL == ctx) {
return NULL;
}
@@ -149,5 +154,5 @@ SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo&
return NULL;
}
- return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), true, trm, true));
+ return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), true, props, true));
}
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 13f215589f..cd4f049c41 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -18,8 +18,9 @@ public:
static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue);
SkSurface_Raster(const SkImageInfo&, void*, size_t rb,
- void (*releaseProc)(void* pixels, void* context), void* context);
- SkSurface_Raster(SkPixelRef*);
+ void (*releaseProc)(void* pixels, void* context), void* context,
+ const SkSurfaceProps*);
+ SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*);
virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
@@ -78,15 +79,16 @@ bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) {
}
SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb,
- void (*releaseProc)(void* pixels, void* context), void* context)
- : INHERITED(info)
+ void (*releaseProc)(void* pixels, void* context), void* context,
+ const SkSurfaceProps* props)
+ : INHERITED(info, props)
{
fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context);
fWeOwnThePixels = false; // We are "Direct"
}
-SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr)
- : INHERITED(pr->info().width(), pr->info().height())
+SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props)
+ : INHERITED(pr->info().width(), pr->info().height(), props)
{
const SkImageInfo& info = pr->info();
@@ -100,7 +102,7 @@ SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr)
}
SkCanvas* SkSurface_Raster::onNewCanvas() {
- return SkNEW_ARGS(SkCanvas, (fBitmap));
+ return SkNEW_ARGS(SkCanvas, (fBitmap, this->props()));
}
SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) {
@@ -140,7 +142,7 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, size_t rb,
void (*releaseProc)(void* pixels, void* context),
- void* context) {
+ void* context, const SkSurfaceProps* props) {
if (NULL == releaseProc) {
context = NULL;
}
@@ -151,14 +153,15 @@ SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void*
return NULL;
}
- return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rb, releaseProc, context));
+ return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rb, releaseProc, context, props));
}
-SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
- return NewRasterDirectReleaseProc(info, pixels, rowBytes, NULL, NULL);
+SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ const SkSurfaceProps* props) {
+ return NewRasterDirectReleaseProc(info, pixels, rowBytes, NULL, NULL, props);
}
-SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
+SkSurface* SkSurface::NewRaster(const SkImageInfo& info, const SkSurfaceProps* props) {
if (!SkSurface_Raster::Valid(info)) {
return NULL;
}
@@ -167,5 +170,5 @@ SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
if (NULL == pr.get()) {
return NULL;
}
- return SkNEW_ARGS(SkSurface_Raster, (pr));
+ return SkNEW_ARGS(SkSurface_Raster, (pr, props));
}
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index f4ea694451..aa6b521887 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1261,8 +1261,8 @@ void SkPDFDevice::onDetachFromCanvas() {
fClipStack = NULL;
}
-SkSurface* SkPDFDevice::newSurface(const SkImageInfo& info) {
- return SkSurface::NewRaster(info);
+SkSurface* SkPDFDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+ return SkSurface::NewRaster(info, &props);
}
ContentEntry* SkPDFDevice::getLastContentEntry() {
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp
index 5b32502d8e..3e3075cc13 100644
--- a/src/ports/SkImageDecoder_CG.cpp
+++ b/src/ports/SkImageDecoder_CG.cpp
@@ -40,6 +40,7 @@ static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) {
static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) {
CGDataProviderRef data = SkStreamToDataProvider(stream);
+ SkASSERT(data);
CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0);
CGDataProviderRelease(data);
return imageSrc;
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index cce5dde538..c8402dda4a 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -161,7 +161,7 @@ public:
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
- virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
protected:
virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
@@ -474,8 +474,8 @@ SkBaseDevice* SkDeferredDevice::onCreateDevice(const SkImageInfo& info, Usage us
return immediateDevice()->createCompatibleDevice(info);
}
-SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info) {
- return this->immediateDevice()->newSurface(info);
+SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+ return this->immediateDevice()->newSurface(info, props);
}
bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index 2938326aba..d234c8ca27 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -51,7 +51,7 @@ static SkPMColor read_pixel(SkSurface* surface, int x, int y) {
class MockSurface : public SkSurface_Base {
public:
- MockSurface(int width, int height) : SkSurface_Base(width, height) {
+ MockSurface(int width, int height) : SkSurface_Base(width, height, NULL) {
clearCounts();
fBitmap.allocN32Pixels(width, height);
}
@@ -706,7 +706,7 @@ static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFac
return;
}
- surface = SkSurface::NewRenderTarget(context, imageSpec);
+ surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
} else
#endif
{
@@ -788,8 +788,8 @@ static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
if (NULL == context) {
continue;
}
- surface = SkSurface::NewRenderTarget(context, imageSpec);
- alternateSurface = SkSurface::NewRenderTarget(context, imageSpec);
+ surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+ alternateSurface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
} else
#endif
{
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index f0148ba9a2..3e47a05ba3 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -56,7 +56,8 @@ DEF_GPUTEST(GpuDrawPath, reporter, factory) {
for (size_t i = 0; i < SK_ARRAY_COUNT(sampleCounts); ++i) {
SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255);
- SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(grContext, info, sampleCounts[i]));
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(grContext, info,
+ sampleCounts[i], NULL));
test_drawPathEmpty(reporter, surface->getCanvas());
}
}
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 8b6e4285ca..b1d087825b 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -1000,10 +1000,13 @@ DEF_TEST(XfermodeImageFilterCroppedInput, reporter) {
}
#if SK_SUPPORT_GPU
+const SkSurfaceProps gProps = SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+
DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
SkImageInfo::MakeN32Premul(100, 100),
+ gProps,
0));
test_crop_rects(device, reporter);
}
@@ -1012,6 +1015,7 @@ DEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) {
GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
SkImageInfo::MakeN32Premul(100, 100),
+ gProps,
0));
test_huge_blur(device, reporter);
}
@@ -1020,6 +1024,7 @@ DEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) {
GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
SkImageInfo::MakeN32Premul(1, 1),
+ gProps,
0));
test_xfermode_cropped_input(device, reporter);
}
@@ -1028,6 +1033,7 @@ DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) {
GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
SkImageInfo::MakeN32Premul(1, 1),
+ gProps,
0));
test_negative_blur_sigma(device, reporter);
}
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
index 8bdb77012a..ce45f16258 100644
--- a/tests/PremulAlphaRoundTripTest.cpp
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -90,7 +90,8 @@ DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
continue;
}
- device.reset(SkGpuDevice::Create(context, info, 0));
+ device.reset(SkGpuDevice::Create(context, info,
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), 0));
#else
continue;
#endif
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index a320347637..385a17ead0 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -81,7 +81,8 @@ DEF_GPUTEST(ReadWriteAlpha, reporter, factory) {
REPORTER_ASSERT(reporter, match);
// Now try writing on the single channel texture
- SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget()));
+ SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(),
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
SkCanvas canvas(device);
SkPaint paint;
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 9a4a129c7f..f9f94d1b27 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -298,7 +298,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) {
desc.fWidth = gWidth;
desc.fHeight = gHeight;
SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
- SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info, 0));
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info));
test_cache(reporter, context, surface->getCanvas());
test_purge_invalidated(reporter, context);
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 63e47f1997..69c8b845ec 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -52,7 +52,7 @@ static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
}
case kGpu_SurfaceType:
#if SK_SUPPORT_GPU
- return context ? SkSurface::NewRenderTarget(context, info) : NULL;
+ return context ? SkSurface::NewRenderTarget(context, info, 0, NULL) : NULL;
#endif
break;
case kGpuScratch_SurfaceType:
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 8148a2b625..705849d01a 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -157,7 +157,8 @@ SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
return NULL;
}
- SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target));
+ SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target,
+ SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
canvas = SkNEW_ARGS(SkCanvas, (device.get()));
break;
}