From 18ca68b79a60b2de95ae89da3075df2ee3241471 Mon Sep 17 00:00:00 2001 From: "mark@chromium.org" Date: Mon, 15 Jun 2009 19:05:44 +0000 Subject: Properly use data when creating a bitmap platform canvas. Gets things painting on the screen again. Regressed in r18363. Review URL: http://codereview.chromium.org/126140 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18415 0039d316-1c4b-4281-b951-d872f2087c98 --- skia/ext/bitmap_platform_device_mac.cc | 70 +++++++++++++++++++++++----------- skia/ext/bitmap_platform_device_mac.h | 20 +++++----- skia/ext/platform_canvas_mac.cc | 7 ++-- 3 files changed, 60 insertions(+), 37 deletions(-) (limited to 'skia') diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc index 79c735a..2daf772 100644 --- a/skia/ext/bitmap_platform_device_mac.cc +++ b/skia/ext/bitmap_platform_device_mac.cc @@ -44,6 +44,28 @@ bool Constrain(int available_size, int* position, int *size) { return true; } +static CGContextRef CGContextForData(void* data, int width, int height) { + CGColorSpaceRef color_space = + CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + // Allocate a bitmap context with 4 components per pixel (BGRA). Apple + // recommends these flags for improved CG performance. + CGContextRef context = + CGBitmapContextCreate(data, width, height, 8, width * 4, + color_space, + kCGImageAlphaPremultipliedFirst | + kCGBitmapByteOrder32Host); + CGColorSpaceRelease(color_space); + + if (!context) + return NULL; + + // Change the coordinate system to match WebCore's + CGContextTranslateCTM(context, 0, height); + CGContextScaleCTM(context, 1.0, -1.0); + + return context; +} + } // namespace class BitmapPlatformDevice::BitmapPlatformDeviceData : public SkRefCnt { @@ -153,15 +175,20 @@ void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() { // that we can create the pixel data before calling the constructor. This is // required so that we can call the base class' constructor with the pixel // data. -BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context, - int width, - int height, - bool is_opaque) { +BitmapPlatformDevice* BitmapPlatformDevice::CreateWithContext( + CGContextRef context, int width, int height, bool is_opaque) { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); if (bitmap.allocPixels() != true) return NULL; - void* data = bitmap.getPixels(); + + void* data = NULL; + if (context) { + data = CGBitmapContextGetData(context); + bitmap.setPixels(data); + } else { + data = bitmap.getPixels(); + } // Note: The Windows implementation clears the Bitmap later on. // This bears mentioning since removal of this line makes the @@ -170,36 +197,33 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context, bitmap.setIsOpaque(is_opaque); - if (is_opaque) { #ifndef NDEBUG + if (is_opaque) { // To aid in finding bugs, we set the background color to something // obviously wrong so it will be noticable when it is not cleared bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green -#endif } +#endif - if (!context) { - CGColorSpaceRef color_space = - CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - // allocate a bitmap context with 4 components per pixel (BGRA). Apple - // recommends these flags for improved CG performance. - context = - CGBitmapContextCreate(data, width, height, 8, width*4, - color_space, - kCGImageAlphaPremultipliedFirst | - kCGBitmapByteOrder32Host); - - // Change the coordinate system to match WebCore's - CGContextTranslateCTM(context, 0, height); - CGContextScaleCTM(context, 1.0, -1.0); - CGColorSpaceRelease(color_space); - } + if (!context) + context = CGContextForData(data, width, height); // The device object will take ownership of the graphics context. return new BitmapPlatformDevice( new BitmapPlatformDeviceData(context), bitmap); } +BitmapPlatformDevice* BitmapPlatformDevice::CreateWithData(uint8_t* data, + int width, + int height, + bool is_opaque) { + CGContextRef context = NULL; + if (data) + context = CGContextForData(data, width, height); + + return CreateWithContext(context, width, height, is_opaque); +} + // The device will own the bitmap, which corresponds to also owning the pixel // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. BitmapPlatformDevice::BitmapPlatformDevice( diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h index 6580302..d293cd4 100644 --- a/skia/ext/bitmap_platform_device_mac.h +++ b/skia/ext/bitmap_platform_device_mac.h @@ -25,17 +25,15 @@ namespace skia { // DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead. class BitmapPlatformDevice : public PlatformDevice { public: - // Factory function. The screen DC is used to create the bitmap, and will not - // be stored beyond this function. is_opaque should be set if the caller - // knows the bitmap will be completely opaque and allows some optimizations. - // - // The shared_section parameter is optional (pass NULL for default behavior). - // If shared_section is non-null, then it must be a handle to a file-mapping - // object returned by CreateFileMapping. See CreateDIBSection for details. - static BitmapPlatformDevice* Create(CGContextRef context, - int width, - int height, - bool is_opaque); + // |context| may be NULL. + static BitmapPlatformDevice* CreateWithContext(CGContextRef context, + int width, int height, + bool is_opaque); + + // Creates a context for |data| and calls CreateWithContext. + static BitmapPlatformDevice* CreateWithData(uint8_t* data, + int width, int height, + bool is_opaque); // Copy constructor. When copied, devices duplicate their internal data, so // stay linked. This is because their implementation is very heavyweight diff --git a/skia/ext/platform_canvas_mac.cc b/skia/ext/platform_canvas_mac.cc index 4e42bb1..e75e55aa 100644 --- a/skia/ext/platform_canvas_mac.cc +++ b/skia/ext/platform_canvas_mac.cc @@ -40,8 +40,8 @@ bool PlatformCanvas::initialize(int width, int height, bool is_opaque, uint8_t* data) { - SkDevice* device = BitmapPlatformDevice::Create(NULL, width, height, - is_opaque); + SkDevice* device = BitmapPlatformDevice::CreateWithData(data, width, height, + is_opaque); if (!device) return false; @@ -63,7 +63,8 @@ SkDevice* PlatformCanvas::createDevice(SkBitmap::Config config, int height, bool is_opaque, bool isForLayer) { SkASSERT(config == SkBitmap::kARGB_8888_Config); - return BitmapPlatformDevice::Create(NULL, width, height, is_opaque); + return BitmapPlatformDevice::CreateWithContext(NULL, width, height, + is_opaque); } } // namespace skia -- cgit v1.1