diff options
author | reed@google.com <reed@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 19:57:15 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 19:57:15 +0000 |
commit | 3b798343ad6244041f094ab1c7929cddef451945 (patch) | |
tree | f95ab6f60499c493016870931161e879a86e2e6f /skia/ext | |
parent | b27ccd4d945890566a5897d7dc903ebd67c76948 (diff) | |
download | chromium_src-3b798343ad6244041f094ab1c7929cddef451945.zip chromium_src-3b798343ad6244041f094ab1c7929cddef451945.tar.gz chromium_src-3b798343ad6244041f094ab1c7929cddef451945.tar.bz2 |
Introduce PlatformBitmap, which is a minimal helper class that wraps an SkBitmap
and a PlatformSurface. This is used to replace the PlatformCanvas that was being
passed to BackingStore to return pixels.
The problem to solve is that PlatformCanvas is an extension of SkCanvas, and
SkCanvas is losing the ability to have its backend specified after its
constructor (for performance reasons).
The BackingStore interface only needs to return a copy of its pixels, and offer
a platform-specific way to draw into it (i.e. BitBlt). The PlatformSurface is
sufficient for this, so the larger infrastructure of PlatformCanvas/PlatformDevice
is not required.
Review URL: https://codereview.chromium.org/11031055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161163 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext')
-rw-r--r-- | skia/ext/bitmap_platform_device_android.cc | 15 | ||||
-rw-r--r-- | skia/ext/bitmap_platform_device_linux.cc | 26 | ||||
-rw-r--r-- | skia/ext/bitmap_platform_device_mac.cc | 25 | ||||
-rw-r--r-- | skia/ext/bitmap_platform_device_win.cc | 88 | ||||
-rw-r--r-- | skia/ext/platform_canvas.cc | 2 | ||||
-rw-r--r-- | skia/ext/platform_canvas.h | 23 |
6 files changed, 148 insertions, 31 deletions
diff --git a/skia/ext/bitmap_platform_device_android.cc b/skia/ext/bitmap_platform_device_android.cc index f49b6a8..6a71fb2 100644 --- a/skia/ext/bitmap_platform_device_android.cc +++ b/skia/ext/bitmap_platform_device_android.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "skia/ext/bitmap_platform_device_android.h" +#include "skia/ext/platform_canvas.h" namespace skia { @@ -71,4 +72,18 @@ void BitmapPlatformDevice::DrawToNativeContext( SkASSERT(false); } +// Port of PlatformBitmap to android + +PlatformBitmap::~PlatformBitmap() {} + +bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { + bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height); + if (!bitmap_.allocPixels()) + return false; + + bitmap_.setIsOpaque(is_opaque); + surface_ = bitmap_.getPixels(); + return true; +} + } // namespace skia diff --git a/skia/ext/bitmap_platform_device_linux.cc b/skia/ext/bitmap_platform_device_linux.cc index 562e7fc..63b44a6 100644 --- a/skia/ext/bitmap_platform_device_linux.cc +++ b/skia/ext/bitmap_platform_device_linux.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "skia/ext/bitmap_platform_device_linux.h" - #include "skia/ext/bitmap_platform_device_data.h" +#include "skia/ext/platform_canvas.h" #if defined(OS_OPENBSD) #include <cairo.h> @@ -176,4 +176,28 @@ void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, data_->SetMatrixClip(transform, region); } +// Port of PlatformBitmap to linux + +PlatformBitmap::~PlatformBitmap() { + cairo_destroy(surface_); +} + +bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { + cairo_surface_t* surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + width, height); + if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(surf); + return false; + } + + bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, + cairo_image_surface_get_stride(surf)); + bitmap_.setPixels(cairo_image_surface_get_data(surf)); + bitmap_.setIsOpaque(is_opaque); + + surface_ = cairo_create(surf); + cairo_surface_destroy(surf); + return true; +} + } // namespace skia diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc index b0cb888..d8f16a2 100644 --- a/skia/ext/bitmap_platform_device_mac.cc +++ b/skia/ext/bitmap_platform_device_mac.cc @@ -10,6 +10,7 @@ #include "base/mac/mac_util.h" #include "base/memory/ref_counted.h" #include "skia/ext/bitmap_platform_device_data.h" +#include "skia/ext/platform_canvas.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkRegion.h" @@ -254,4 +255,28 @@ SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice( return bitmap_device; } +// Port of PlatformBitmap to mac + +PlatformBitmap::~PlatformBitmap() { + if (surface_) + CGContextRelease(surface_); +} + +bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { + if (RasterDeviceTooBigToAllocate(width, height)) + return false; + + bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, width * 4); + if (!bitmap_.allocPixels()) + return false; + + if (!is_opaque) + bitmap_.eraseColor(0); + bitmap_.setIsOpaque(is_opaque); + + surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), + bitmap_.height()); + return true; +} + } // namespace skia diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index a52dd4e..12b9266 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc @@ -6,13 +6,46 @@ #include <psapi.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" #include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkUtils.h" +static HBITMAP CreateHBitmap(int width, int height, bool is_opaque, + HANDLE shared_section, SkBitmap* output) { + // CreateDIBSection appears to get unhappy if we create an empty bitmap, so + // just create a minimal bitmap + if ((width == 0) || (height == 0)) { + width = 1; + height = 1; + } + + BITMAPINFOHEADER hdr = {0}; + hdr.biSize = sizeof(BITMAPINFOHEADER); + hdr.biWidth = width; + hdr.biHeight = -height; // minus means top-down bitmap + hdr.biPlanes = 1; + hdr.biBitCount = 32; + hdr.biCompression = BI_RGB; // no compression + hdr.biSizeImage = 0; + hdr.biXPelsPerMeter = 1; + hdr.biYPelsPerMeter = 1; + hdr.biClrUsed = 0; + hdr.biClrImportant = 0; + + void* data = NULL; + HBITMAP hbitmap = CreateDIBSection(NULL, reinterpret_cast<BITMAPINFO*>(&hdr), + 0, &data, shared_section, 0); + if (hbitmap) { + output->setConfig(SkBitmap::kARGB_8888_Config, width, height); + output->setPixels(data); + output->setIsOpaque(is_opaque); + } + return hbitmap; +} + namespace skia { BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( @@ -94,38 +127,11 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create( HANDLE shared_section) { SkBitmap bitmap; - // CreateDIBSection appears to get unhappy if we create an empty bitmap, so - // just create a minimal bitmap - if ((width == 0) || (height == 0)) { - width = 1; - height = 1; - } - - BITMAPINFOHEADER hdr = {0}; - hdr.biSize = sizeof(BITMAPINFOHEADER); - hdr.biWidth = width; - hdr.biHeight = -height; // minus means top-down bitmap - hdr.biPlanes = 1; - hdr.biBitCount = 32; - hdr.biCompression = BI_RGB; // no compression - hdr.biSizeImage = 0; - hdr.biXPelsPerMeter = 1; - hdr.biYPelsPerMeter = 1; - hdr.biClrUsed = 0; - hdr.biClrImportant = 0; - - void* data = NULL; - HBITMAP hbitmap = CreateDIBSection(NULL, - reinterpret_cast<BITMAPINFO*>(&hdr), 0, - &data, - shared_section, 0); + HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, shared_section, + &bitmap); if (!hbitmap) return NULL; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap.setPixels(data); - bitmap.setIsOpaque(is_opaque); - #ifndef NDEBUG // If we were given data, then don't clobber it! if (!shared_section && is_opaque) @@ -262,4 +268,26 @@ SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice( return bitmap_device; } +// Port of PlatformBitmap to win + +PlatformBitmap::~PlatformBitmap() { + if (surface_) + DeleteDC(surface_); +} + +bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { + HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, 0, &bitmap_); + if (!hbitmap) + return false; + + surface_ = CreateCompatibleDC(NULL); + InitializeDC(surface_); + HGDIOBJ old_bitmap = SelectObject(surface_, 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. + DeleteObject(old_bitmap); + return true; +} + } // namespace skia diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc index 4378b90..7e70165 100644 --- a/skia/ext/platform_canvas.cc +++ b/skia/ext/platform_canvas.cc @@ -87,4 +87,6 @@ void MakeOpaque(SkCanvas* canvas, int x, int y, int width, int height) { canvas->drawRect(rect, paint); } +PlatformBitmap::PlatformBitmap() : surface_(0) {} + } // namespace skia diff --git a/skia/ext/platform_canvas.h b/skia/ext/platform_canvas.h index e030ad7..4d2b0c0 100644 --- a/skia/ext/platform_canvas.h +++ b/skia/ext/platform_canvas.h @@ -7,6 +7,7 @@ // The platform-specific device will include the necessary platform headers // to get the surface type. +#include "base/basictypes.h" #include "skia/ext/platform_device.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -151,6 +152,28 @@ class SK_API ScopedPlatformPaint { ScopedPlatformPaint& operator=(const ScopedPlatformPaint&); }; +class SK_API PlatformBitmap { + public: + PlatformBitmap(); + ~PlatformBitmap(); + + // Returns true if the bitmap was able to allocate its surface. + bool Allocate(int width, int height, bool is_opaque); + + // Returns the platform surface, or 0 if Allocate() did not return true. + PlatformSurface GetSurface() { return surface_; } + + // Return the skia bitmap, which will be empty if Allocate() did not + // return true. + const SkBitmap& GetBitmap() { return bitmap_; } + + private: + SkBitmap bitmap_; + PlatformSurface surface_; + + DISALLOW_COPY_AND_ASSIGN(PlatformBitmap); +}; + } // namespace skia #endif // SKIA_EXT_PLATFORM_CANVAS_H_ |