summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authorsenorblanco@chromium.org <senorblanco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-02 22:44:07 +0000
committersenorblanco@chromium.org <senorblanco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-02 22:44:07 +0000
commit9abceb78361ca70703fdf6051eb4e556f06f2b6a (patch)
tree2906b780dc22793414466f83e7d050af2e0d638e /skia
parentfbc94488149d051eb37f09e9e5ba546f9d18880e (diff)
downloadchromium_src-9abceb78361ca70703fdf6051eb4e556f06f2b6a.zip
chromium_src-9abceb78361ca70703fdf6051eb4e556f06f2b6a.tar.gz
chromium_src-9abceb78361ca70703fdf6051eb4e556f06f2b6a.tar.bz2
Remove BitmapPlatformDeviceData, and merge its functionality into the appropriate BitmapPlatformDevice. It was a little twisty maze of #ifdefs, ostensibly created to allow successful assignment and copy construction of the device. However, I could not find any such use, and the BitmapPlatformDevices are all marked DISALLOW_COPY_AND_ASSIGN!
Instead, we use a subclass of SkPixelRef to handle ownership of the platform-specific bitmaps. This allows correct Skia semantics: the SkBitmap used for device drawing can safely outlive the device, since it is refcounted. Such a subclass already existed for Windows; this simply implements it for Cairo as well, and uses it in all cases. TBR=brettw Review URL: https://codereview.chromium.org/95773002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238213 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ext/bitmap_platform_device_cairo.cc97
-rw-r--r--skia/ext/bitmap_platform_device_cairo.h29
-rw-r--r--skia/ext/bitmap_platform_device_data.h102
-rw-r--r--skia/ext/bitmap_platform_device_mac.cc67
-rw-r--r--skia/ext/bitmap_platform_device_mac.h35
-rw-r--r--skia/ext/bitmap_platform_device_win.cc76
-rw-r--r--skia/ext/bitmap_platform_device_win.h58
-rw-r--r--skia/skia_chrome.gypi1
8 files changed, 212 insertions, 253 deletions
diff --git a/skia/ext/bitmap_platform_device_cairo.cc b/skia/ext/bitmap_platform_device_cairo.cc
index e931629..906f95c 100644
--- a/skia/ext/bitmap_platform_device_cairo.cc
+++ b/skia/ext/bitmap_platform_device_cairo.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "skia/ext/bitmap_platform_device_cairo.h"
-#include "skia/ext/bitmap_platform_device_data.h"
#include "skia/ext/platform_canvas.h"
#if defined(OS_OPENBSD)
@@ -16,6 +15,42 @@ namespace skia {
namespace {
+// CairoSurfacePixelRef is an SkPixelRef that is backed by a cairo surface.
+class SK_API CairoSurfacePixelRef : public SkPixelRef {
+ public:
+ // The constructor takes ownership of the passed-in surface.
+ explicit CairoSurfacePixelRef(cairo_surface_t* surface);
+ virtual ~CairoSurfacePixelRef();
+
+ SK_DECLARE_UNFLATTENABLE_OBJECT();
+
+ protected:
+ virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
+ virtual void onUnlockPixels() SK_OVERRIDE;
+
+ private:
+ cairo_surface_t* surface_;
+};
+
+CairoSurfacePixelRef::CairoSurfacePixelRef(cairo_surface_t* surface)
+ : surface_(surface) {
+}
+
+CairoSurfacePixelRef::~CairoSurfacePixelRef() {
+ if (surface_)
+ cairo_surface_destroy(surface_);
+}
+
+void* CairoSurfacePixelRef::onLockPixels(SkColorTable** color_table) {
+ *color_table = NULL;
+ return cairo_image_surface_get_data(surface_);
+}
+
+void CairoSurfacePixelRef::onUnlockPixels() {
+ // Nothing to do.
+ return;
+}
+
void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
cairo_matrix_t cairo_matrix;
cairo_matrix_init(&cairo_matrix,
@@ -41,20 +76,7 @@ void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
} // namespace
-BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
- cairo_surface_t* surface)
- : surface_(surface),
- config_dirty_(true),
- transform_(SkMatrix::I()) { // Want to load the config next time.
- bitmap_context_ = cairo_create(surface);
-}
-
-BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
- cairo_destroy(bitmap_context_);
- cairo_surface_destroy(surface_);
-}
-
-void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
+void BitmapPlatformDevice::SetMatrixClip(
const SkMatrix& transform,
const SkRegion& region) {
transform_ = transform;
@@ -62,18 +84,18 @@ void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
config_dirty_ = true;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
- if (!config_dirty_ || !bitmap_context_)
+void BitmapPlatformDevice::LoadConfig() {
+ if (!config_dirty_ || !cairo_)
return; // Nothing to do.
config_dirty_ = false;
// Load the identity matrix since this is what our clip is relative to.
cairo_matrix_t cairo_matrix;
cairo_matrix_init_identity(&cairo_matrix);
- cairo_set_matrix(bitmap_context_, &cairo_matrix);
+ cairo_set_matrix(cairo_, &cairo_matrix);
- LoadClipToContext(bitmap_context_, clip_region_);
- LoadMatrixToContext(bitmap_context_, transform_);
+ LoadClipToContext(cairo_, clip_region_);
+ LoadMatrixToContext(cairo_, transform_);
}
// We use this static factory function instead of the regular constructor so
@@ -91,11 +113,11 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
cairo_image_surface_get_stride(surface),
is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
- bitmap.setPixels(cairo_image_surface_get_data(surface));
+ RefPtr<SkPixelRef> pixel_ref = AdoptRef(new CairoSurfacePixelRef(surface));
+ bitmap.setPixelRef(pixel_ref.get());
// The device object will take ownership of the graphics context.
- return new BitmapPlatformDevice
- (bitmap, new BitmapPlatformDeviceData(surface));
+ return new BitmapPlatformDevice(bitmap, surface);
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
@@ -136,13 +158,16 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
// data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
const SkBitmap& bitmap,
- BitmapPlatformDeviceData* data)
+ cairo_surface_t* surface)
: SkBitmapDevice(bitmap),
- data_(data) {
+ cairo_(cairo_create(surface)),
+ config_dirty_(true),
+ transform_(SkMatrix::I()) { // Want to load the config next time.
SetPlatformDevice(this, this);
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
+ cairo_destroy(cairo_);
}
SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
@@ -153,15 +178,14 @@ SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
}
cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
- data_->LoadConfig();
- cairo_t* cairo = data_->bitmap_context();
- cairo_surface_t* surface = cairo_get_target(cairo);
+ LoadConfig();
+ cairo_surface_t* surface = cairo_get_target(cairo_);
// Tell cairo to flush anything it has pending.
cairo_surface_flush(surface);
// Tell Cairo that we (probably) modified (actually, will modify) its pixel
// buffer directly.
cairo_surface_mark_dirty(surface);
- return cairo;
+ return cairo_;
}
void BitmapPlatformDevice::DrawToNativeContext(
@@ -173,7 +197,7 @@ void BitmapPlatformDevice::DrawToNativeContext(
void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
const SkRegion& region,
const SkClipStack&) {
- data_->SetMatrixClip(transform, region);
+ SetMatrixClip(transform, region);
}
// PlatformCanvas impl
@@ -197,22 +221,17 @@ bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, stride,
is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
- if (!bitmap_.allocPixels()) // Using the default allocator.
- return false;
- cairo_surface_t* surf = cairo_image_surface_create_for_data(
- reinterpret_cast<unsigned char*>(bitmap_.getPixels()),
+ cairo_surface_t* surf = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32,
width,
- height,
- stride);
+ height);
if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(surf);
return false;
}
-
- surface_ = cairo_create(surf);
- cairo_surface_destroy(surf);
+ RefPtr<SkPixelRef> pixel_ref = AdoptRef(new CairoSurfacePixelRef(surf));
+ bitmap_.setPixelRef(pixel_ref.get());
return true;
}
diff --git a/skia/ext/bitmap_platform_device_cairo.h b/skia/ext/bitmap_platform_device_cairo.h
index 914be34..5b3c46c 100644
--- a/skia/ext/bitmap_platform_device_cairo.h
+++ b/skia/ext/bitmap_platform_device_cairo.h
@@ -57,9 +57,6 @@ namespace skia {
// case we'll probably create the buffer from a precreated region of memory.
// -----------------------------------------------------------------------------
class BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice {
- // A reference counted cairo surface
- class BitmapPlatformDeviceData;
-
public:
// Create a BitmapPlatformDeviceLinux from an already constructed bitmap;
// you should probably be using Create(). This may become private later if
@@ -67,7 +64,7 @@ class BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice {
// the Windows and Mac versions of this class do.
//
// This object takes ownership of @data.
- BitmapPlatformDevice(const SkBitmap& other, BitmapPlatformDeviceData* data);
+ BitmapPlatformDevice(const SkBitmap& other, cairo_surface_t* surface);
virtual ~BitmapPlatformDevice();
// Constructs a device with size |width| * |height| with contents initialized
@@ -104,7 +101,29 @@ class BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice {
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
cairo_surface_t* surface);
- scoped_refptr<BitmapPlatformDeviceData> data_;
+ // Sets the transform and clip operations. This will not update the Cairo
+ // context, but will mark the config as dirty. The next call of LoadConfig
+ // will pick up these changes.
+ void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
+
+ // Loads the current transform and clip into the context.
+ void LoadConfig();
+
+ // Graphics context used to draw into the surface.
+ cairo_t* cairo_;
+
+ // True when there is a transform or clip that has not been set to the
+ // context. The context is retrieved for every text operation, and the
+ // transform and clip do not change as much. We can save time by not loading
+ // the clip and transform for every one.
+ bool config_dirty_;
+
+ // Translation assigned to the context: we need to keep track of this
+ // separately so it can be updated even if the context isn't created yet.
+ SkMatrix transform_;
+
+ // The current clipping
+ SkRegion clip_region_;
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
diff --git a/skia/ext/bitmap_platform_device_data.h b/skia/ext/bitmap_platform_device_data.h
deleted file mode 100644
index 81e81ed7..0000000
--- a/skia/ext/bitmap_platform_device_data.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
-#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
-
-#include "skia/ext/bitmap_platform_device.h"
-
-namespace skia {
-
-class BitmapPlatformDevice::BitmapPlatformDeviceData :
-#if defined(WIN32) || defined(__APPLE__)
- public SkRefCnt {
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
- // These objects are reference counted and own a Cairo surface. The surface
- // is the backing store for a Skia bitmap and we reference count it so that
- // we can copy BitmapPlatformDevice objects without having to copy all the
- // image data.
- public base::RefCounted<BitmapPlatformDeviceData> {
-#endif
-
- public:
-#if defined(WIN32)
- typedef HBITMAP PlatformContext;
-#elif defined(__APPLE__)
- typedef CGContextRef PlatformContext;
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
- typedef cairo_t* PlatformContext;
-#endif
-
-#if defined(WIN32) || defined(__APPLE__)
- explicit BitmapPlatformDeviceData(PlatformContext bitmap);
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
- explicit BitmapPlatformDeviceData(cairo_surface_t* surface);
-#endif
-
-#if defined(WIN32)
- // Create/destroy hdc_, which is the memory DC for our bitmap data.
- HDC GetBitmapDC();
- void ReleaseBitmapDC();
- bool IsBitmapDCCreated() const;
-#endif
-
-#if defined(__APPLE__)
- void ReleaseBitmapContext();
-#endif // defined(__APPLE__)
-
- // Sets the transform and clip operations. This will not update the CGContext,
- // but will mark the config as dirty. The next call of LoadConfig will
- // pick up these changes.
- void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- // Loads the current transform and clip into the context. Can be called even
- // when |bitmap_context_| is NULL (will be a NOP).
- void LoadConfig();
-
- const SkMatrix& transform() const {
- return transform_;
- }
-
- PlatformContext bitmap_context() {
- return bitmap_context_;
- }
-
- private:
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
- friend class base::RefCounted<BitmapPlatformDeviceData>;
-#endif
- virtual ~BitmapPlatformDeviceData();
-
- // Lazily-created graphics context used to draw into the bitmap.
- PlatformContext bitmap_context_;
-
-#if defined(WIN32)
- // Lazily-created DC used to draw into the bitmap, see GetBitmapDC().
- HDC hdc_;
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
- cairo_surface_t *const surface_;
-#endif
-
- // True when there is a transform or clip that has not been set to the
- // context. The context is retrieved for every text operation, and the
- // transform and clip do not change as much. We can save time by not loading
- // the clip and transform for every one.
- bool config_dirty_;
-
- // Translation assigned to the context: we need to keep track of this
- // separately so it can be updated even if the context isn't created yet.
- SkMatrix transform_;
-
- // The current clipping
- SkRegion clip_region_;
-
- // Disallow copy & assign.
- BitmapPlatformDeviceData(const BitmapPlatformDeviceData&);
- BitmapPlatformDeviceData& operator=(const BitmapPlatformDeviceData&);
-};
-
-} // namespace skia
-
-#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc
index 8525cd3..a62c3cf 100644
--- a/skia/ext/bitmap_platform_device_mac.cc
+++ b/skia/ext/bitmap_platform_device_mac.cc
@@ -9,7 +9,7 @@
#include "base/mac/mac_util.h"
#include "base/memory/ref_counted.h"
-#include "skia/ext/bitmap_platform_device_data.h"
+#include "skia/ext/bitmap_platform_device.h"
#include "skia/ext/platform_canvas.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkMatrix.h"
@@ -57,37 +57,13 @@ static CGContextRef CGContextForData(void* data, int width, int height) {
} // namespace
-BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
- CGContextRef bitmap)
- : bitmap_context_(bitmap),
- config_dirty_(true), // Want to load the config next time.
- transform_(SkMatrix::I()) {
- SkASSERT(bitmap_context_);
- // Initialize the clip region to the entire bitmap.
-
- SkIRect rect;
- rect.set(0, 0,
- CGBitmapContextGetWidth(bitmap_context_),
- CGBitmapContextGetHeight(bitmap_context_));
- clip_region_ = SkRegion(rect);
- CGContextRetain(bitmap_context_);
- // We must save the state once so that we can use the restore/save trick
- // in LoadConfig().
- CGContextSaveGState(bitmap_context_);
-}
-
-BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
- if (bitmap_context_)
- CGContextRelease(bitmap_context_);
-}
-
-void BitmapPlatformDevice::BitmapPlatformDeviceData::ReleaseBitmapContext() {
+void BitmapPlatformDevice::ReleaseBitmapContext() {
SkASSERT(bitmap_context_);
CGContextRelease(bitmap_context_);
bitmap_context_ = NULL;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
+void BitmapPlatformDevice::SetMatrixClip(
const SkMatrix& transform,
const SkRegion& region) {
transform_ = transform;
@@ -95,7 +71,7 @@ void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
config_dirty_ = true;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
+void BitmapPlatformDevice::LoadConfig() {
if (!config_dirty_ || !bitmap_context_)
return; // Nothing to do.
config_dirty_ = false;
@@ -156,8 +132,7 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context,
} else
CGContextRetain(context);
- BitmapPlatformDevice* rv = new BitmapPlatformDevice(
- skia::AdoptRef(new BitmapPlatformDeviceData(context)), bitmap);
+ BitmapPlatformDevice* rv = new BitmapPlatformDevice(context, bitmap);
// The device object took ownership of the graphics context with its own
// CGContextRetain call.
@@ -196,37 +171,53 @@ BitmapPlatformDevice* BitmapPlatformDevice::CreateWithData(uint8_t* data,
// The device will own the bitmap, which corresponds to also owning the pixel
// data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
- const skia::RefPtr<BitmapPlatformDeviceData>& data, const SkBitmap& bitmap)
+ CGContextRef context, const SkBitmap& bitmap)
: SkBitmapDevice(bitmap),
- data_(data) {
+ bitmap_context_(context),
+ config_dirty_(true), // Want to load the config next time.
+ transform_(SkMatrix::I()) {
SetPlatformDevice(this, this);
+ SkASSERT(bitmap_context_);
+ // Initialize the clip region to the entire bitmap.
+
+ SkIRect rect;
+ rect.set(0, 0,
+ CGBitmapContextGetWidth(bitmap_context_),
+ CGBitmapContextGetHeight(bitmap_context_));
+ clip_region_ = SkRegion(rect);
+ CGContextRetain(bitmap_context_);
+ // We must save the state once so that we can use the restore/save trick
+ // in LoadConfig().
+ CGContextSaveGState(bitmap_context_);
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
+ if (bitmap_context_)
+ CGContextRelease(bitmap_context_);
}
CGContextRef BitmapPlatformDevice::GetBitmapContext() {
- data_->LoadConfig();
- return data_->bitmap_context();
+ LoadConfig();
+ return bitmap_context_;
}
void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
const SkRegion& region,
const SkClipStack&) {
- data_->SetMatrixClip(transform, region);
+ SetMatrixClip(transform, region);
}
void BitmapPlatformDevice::DrawToNativeContext(CGContextRef context, int x,
int y, const CGRect* src_rect) {
bool created_dc = false;
- if (!data_->bitmap_context()) {
+ if (!bitmap_context_) {
created_dc = true;
GetBitmapContext();
}
// this should not make a copy of the bits, since we're not doing
// anything to trigger copy on write
- CGImageRef image = CGBitmapContextCreateImage(data_->bitmap_context());
+ CGImageRef image = CGBitmapContextCreateImage(bitmap_context_);
CGRect bounds;
bounds.origin.x = x;
bounds.origin.y = y;
@@ -244,7 +235,7 @@ void BitmapPlatformDevice::DrawToNativeContext(CGContextRef context, int x,
CGImageRelease(image);
if (created_dc)
- data_->ReleaseBitmapContext();
+ ReleaseBitmapContext();
}
SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h
index 07b0084..00b0309 100644
--- a/skia/ext/bitmap_platform_device_mac.h
+++ b/skia/ext/bitmap_platform_device_mac.h
@@ -60,21 +60,40 @@ class SK_API BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice
const SkClipStack&) OVERRIDE;
protected:
- // Reference counted data that can be shared between multiple devices. This
- // allows copy constructors and operator= for devices to work properly. The
- // bitmaps used by the base device class are already refcounted and copyable.
- class BitmapPlatformDeviceData;
-
- BitmapPlatformDevice(const skia::RefPtr<BitmapPlatformDeviceData>& data,
+ BitmapPlatformDevice(CGContextRef context,
const SkBitmap& bitmap);
virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
int height, bool isOpaque,
Usage usage) OVERRIDE;
- // Data associated with this device, guaranteed non-null.
- skia::RefPtr<BitmapPlatformDeviceData> data_;
+ private:
+ void ReleaseBitmapContext();
+
+ // Sets the transform and clip operations. This will not update the CGContext,
+ // but will mark the config as dirty. The next call of LoadConfig will
+ // pick up these changes.
+ void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
+
+ // Loads the current transform and clip into the context. Can be called even
+ // when |bitmap_context_| is NULL (will be a NOP).
+ void LoadConfig();
+
+ // Lazily-created graphics context used to draw into the bitmap.
+ CGContextRef bitmap_context_;
+
+ // True when there is a transform or clip that has not been set to the
+ // context. The context is retrieved for every text operation, and the
+ // transform and clip do not change as much. We can save time by not loading
+ // the clip and transform for every one.
+ bool config_dirty_;
+
+ // Translation assigned to the context: we need to keep track of this
+ // separately so it can be updated even if the context isn't created yet.
+ SkMatrix transform_;
+ // The current clipping
+ SkRegion clip_region_;
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc
index 42f431b..0dfc324 100644
--- a/skia/ext/bitmap_platform_device_win.cc
+++ b/skia/ext/bitmap_platform_device_win.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/debug/alias.h"
#include "skia/ext/bitmap_platform_device_win.h"
-#include "skia/ext/bitmap_platform_device_data.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -144,34 +143,11 @@ void PlatformBitmapPixelRef::onUnlockPixels() {
namespace skia {
-BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
- HBITMAP hbitmap)
- : bitmap_context_(hbitmap),
- hdc_(NULL),
- config_dirty_(true), // Want to load the config next time.
- transform_(SkMatrix::I()) {
- // Initialize the clip region to the entire bitmap.
- BITMAP bitmap_data;
- if (GetObject(bitmap_context_, sizeof(BITMAP), &bitmap_data)) {
- SkIRect rect;
- rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
- clip_region_ = SkRegion(rect);
- }
-}
-
-BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
- if (hdc_)
- ReleaseBitmapDC();
-
- // this will free the bitmap data as well as the bitmap handle
- DeleteObject(bitmap_context_);
-}
-
-HDC BitmapPlatformDevice::BitmapPlatformDeviceData::GetBitmapDC() {
+HDC BitmapPlatformDevice::GetBitmapDC() {
if (!hdc_) {
hdc_ = CreateCompatibleDC(NULL);
InitializeDC(hdc_);
- HGDIOBJ old_bitmap = SelectObject(hdc_, bitmap_context_);
+ HGDIOBJ old_bitmap = SelectObject(hdc_, hbitmap_);
// When the memory DC is created, its display surface is exactly one
// monochrome pixel wide and one monochrome pixel high. Since we select our
// own bitmap, we must delete the previous one.
@@ -182,19 +158,19 @@ HDC BitmapPlatformDevice::BitmapPlatformDeviceData::GetBitmapDC() {
return hdc_;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::ReleaseBitmapDC() {
+void BitmapPlatformDevice::ReleaseBitmapDC() {
SkASSERT(hdc_);
DeleteDC(hdc_);
hdc_ = NULL;
}
-bool BitmapPlatformDevice::BitmapPlatformDeviceData::IsBitmapDCCreated()
+bool BitmapPlatformDevice::IsBitmapDCCreated()
const {
return hdc_ != NULL;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
+void BitmapPlatformDevice::SetMatrixClip(
const SkMatrix& transform,
const SkRegion& region) {
transform_ = transform;
@@ -202,7 +178,7 @@ void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
config_dirty_ = true;
}
-void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
+void BitmapPlatformDevice::LoadConfig() {
if (!config_dirty_ || !hdc_)
return; // Nothing to do.
config_dirty_ = false;
@@ -231,7 +207,9 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0,
is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
- bitmap.setPixels(data);
+ RefPtr<SkPixelRef> pixel_ref = AdoptRef(new PlatformBitmapPixelRef(hbitmap,
+ data));
+ bitmap.setPixelRef(pixel_ref.get());
#ifndef NDEBUG
// If we were given data, then don't clobber it!
@@ -243,8 +221,7 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(
// The device object will take ownership of the HBITMAP. The initial refcount
// of the data object will be 1, which is what the constructor expects.
- return new BitmapPlatformDevice(
- skia::AdoptRef(new BitmapPlatformDeviceData(hbitmap)), bitmap);
+ return new BitmapPlatformDevice(hbitmap, bitmap);
}
// static
@@ -267,22 +244,34 @@ BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
// The device will own the HBITMAP, which corresponds to also owning the pixel
// data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
- const skia::RefPtr<BitmapPlatformDeviceData>& data,
+ HBITMAP hbitmap,
const SkBitmap& bitmap)
: SkBitmapDevice(bitmap),
- data_(data) {
+ hbitmap_(hbitmap),
+ hdc_(NULL),
+ config_dirty_(true), // Want to load the config next time.
+ transform_(SkMatrix::I()) {
// The data object is already ref'ed for us by create().
SkDEBUGCODE(begin_paint_count_ = 0);
SetPlatformDevice(this, this);
+ // Initialize the clip region to the entire bitmap.
+ BITMAP bitmap_data;
+ if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
+ SkIRect rect;
+ rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
+ clip_region_ = SkRegion(rect);
+ }
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
SkASSERT(begin_paint_count_ == 0);
+ if (hdc_)
+ ReleaseBitmapDC();
}
HDC BitmapPlatformDevice::BeginPlatformPaint() {
SkDEBUGCODE(begin_paint_count_++);
- return data_->GetBitmapDC();
+ return GetBitmapDC();
}
void BitmapPlatformDevice::EndPlatformPaint() {
@@ -293,12 +282,12 @@ void BitmapPlatformDevice::EndPlatformPaint() {
void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
const SkRegion& region,
const SkClipStack&) {
- data_->SetMatrixClip(transform, region);
+ SetMatrixClip(transform, region);
}
void BitmapPlatformDevice::DrawToNativeContext(HDC dc, int x, int y,
const RECT* src_rect) {
- bool created_dc = !data_->IsBitmapDCCreated();
+ bool created_dc = !IsBitmapDCCreated();
HDC source_dc = BeginPlatformPaint();
RECT temp_rect;
@@ -344,17 +333,17 @@ void BitmapPlatformDevice::DrawToNativeContext(HDC dc, int x, int y,
copy_height,
blend_function);
}
- LoadTransformToDC(source_dc, data_->transform());
+ LoadTransformToDC(source_dc, transform_);
EndPlatformPaint();
if (created_dc)
- data_->ReleaseBitmapDC();
+ ReleaseBitmapDC();
}
const SkBitmap& BitmapPlatformDevice::onAccessBitmap() {
// FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI
// operation has occurred on our DC.
- if (data_->IsBitmapDCCreated())
+ if (IsBitmapDCCreated())
GdiFlush();
return SkBitmapDevice::onAccessBitmap();
}
@@ -404,8 +393,9 @@ bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0,
is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
// PlatformBitmapPixelRef takes ownership of |hbitmap|.
- bitmap_.setPixelRef(
- skia::AdoptRef(new PlatformBitmapPixelRef(hbitmap, data)).get());
+ RefPtr<SkPixelRef> pixel_ref = AdoptRef(new PlatformBitmapPixelRef(hbitmap,
+ data));
+ bitmap_.setPixelRef(pixel_ref.get());
bitmap_.lockPixels();
return true;
diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h
index 1261e51..d2c1603 100644
--- a/skia/ext/bitmap_platform_device_win.h
+++ b/skia/ext/bitmap_platform_device_win.h
@@ -19,13 +19,11 @@ namespace skia {
// This pixel data is provided to the bitmap that the device contains so that it
// can be shared.
//
-// The device owns the pixel data, when the device goes away, the pixel data
-// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
-// reference counting for the pixel data. In normal Skia, you could assign
-// another bitmap to this device's bitmap and everything will work properly.
-// For us, that other bitmap will become invalid as soon as the device becomes
-// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
-// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
+// The GDI bitmap created for drawing is actually owned by a
+// PlatformBitmapPixelRef, and stored in an SkBitmap via the normal skia
+// SkPixelRef refcounting mechanism. In this way, the GDI bitmap can outlive
+// the device created to draw into it. So it is safe to call accessBitmap() on
+// the device, and retain the returned SkBitmap.
class SK_API BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice {
public:
// Factory function. is_opaque should be set if the caller knows the bitmap
@@ -75,17 +73,43 @@ class SK_API BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice
Usage usage) OVERRIDE;
private:
- // Reference counted data that can be shared between multiple devices. This
- // allows copy constructors and operator= for devices to work properly. The
- // bitmaps used by the base device class are already refcounted and copyable.
- class BitmapPlatformDeviceData;
-
// Private constructor.
- BitmapPlatformDevice(const skia::RefPtr<BitmapPlatformDeviceData>& data,
- const SkBitmap& bitmap);
-
- // Data associated with this device, guaranteed non-null.
- skia::RefPtr<BitmapPlatformDeviceData> data_;
+ BitmapPlatformDevice(HBITMAP hbitmap, const SkBitmap& bitmap);
+
+ // Bitmap into which the drawing will be done. This bitmap not owned by this
+ // class, but by the BitmapPlatformPixelRef inside the device's SkBitmap.
+ // It's only stored here in order to lazy-create the DC (below).
+ HBITMAP hbitmap_;
+
+ // Lazily-created DC used to draw into the bitmap; see GetBitmapDC().
+ HDC hdc_;
+
+ // True when there is a transform or clip that has not been set to the
+ // context. The context is retrieved for every text operation, and the
+ // transform and clip do not change as much. We can save time by not loading
+ // the clip and transform for every one.
+ bool config_dirty_;
+
+ // Translation assigned to the context: we need to keep track of this
+ // separately so it can be updated even if the context isn't created yet.
+ SkMatrix transform_;
+
+ // The current clipping region.
+ SkRegion clip_region_;
+
+ // Create/destroy hdc_, which is the memory DC for our bitmap data.
+ HDC GetBitmapDC();
+ void ReleaseBitmapDC();
+ bool IsBitmapDCCreated() const;
+
+ // Sets the transform and clip operations. This will not update the DC,
+ // but will mark the config as dirty. The next call of LoadConfig will
+ // pick up these changes.
+ void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
+
+ // Loads the current transform and clip into the context. Can be called even
+ // when |hbitmap_| is NULL (will be a NOP).
+ void LoadConfig();
#ifdef SK_DEBUG
int begin_paint_count_;
diff --git a/skia/skia_chrome.gypi b/skia/skia_chrome.gypi
index 32179a6..6dcc665 100644
--- a/skia/skia_chrome.gypi
+++ b/skia/skia_chrome.gypi
@@ -28,7 +28,6 @@
'ext/bitmap_platform_device.h',
'ext/bitmap_platform_device_cairo.cc',
'ext/bitmap_platform_device_cairo.h',
- 'ext/bitmap_platform_device_data.h',
'ext/bitmap_platform_device_mac.cc',
'ext/bitmap_platform_device_mac.h',
'ext/bitmap_platform_device_skia.cc',