aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2014-09-22 07:29:03 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-22 07:29:03 -0700
commit4a8126e7f81384526629b1e21bf89b632ea13cd9 (patch)
tree9ee0776304de9dc98e48efc4943dd0fdc45db453 /src/core
parenta29b5d8430ada72bc73b1e6e1b8f09e4b046b2ff (diff)
Introduce Props to surface (patchset #27 id:520001 of https://codereview.chromium.org/551463004/)"
This reverts commit 29c857d0f3a1cb837f73406eeb6ba9771879b5e7. TBR= Author: reed@google.com Review URL: https://codereview.chromium.org/588143004
Diffstat (limited to 'src/core')
-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
9 files changed, 142 insertions, 130 deletions
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