diff options
author | 2014-09-22 07:29:03 -0700 | |
---|---|---|
committer | 2014-09-22 07:29:03 -0700 | |
commit | 4a8126e7f81384526629b1e21bf89b632ea13cd9 (patch) | |
tree | 9ee0776304de9dc98e48efc4943dd0fdc45db453 /src/core | |
parent | a29b5d8430ada72bc73b1e6e1b8f09e4b046b2ff (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.cpp | 4 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 84 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 8 | ||||
-rw-r--r-- | src/core/SkDeviceProperties.h | 107 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 38 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 2 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 2 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 2 | ||||
-rw-r--r-- | src/core/SkSurfacePriv.h | 25 |
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 |