summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 14:41:32 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 14:41:32 +0000
commitf6b50339c9344e050baffe0f9062799fa14c4665 (patch)
treef9123f028e98c1d7c98ac33118295238a1f3208f /gfx
parent7d5ac9e5a0f5f18cac2f2a8b45de1eeab2751a79 (diff)
downloadchromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.zip
chromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.tar.gz
chromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.tar.bz2
Create gfx::ScopedImage. This wraps a gfx::NativeImage and hides the underlying
memory management for each platform under a consistent interface. BUG=none TEST=Compile and gfx_unittests Review URL: http://codereview.chromium.org/3841002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63359 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
-rw-r--r--gfx/gfx.gyp2
-rw-r--r--gfx/native_widget_types.h9
-rw-r--r--gfx/scoped_image.h147
-rw-r--r--gfx/scoped_image_unittest.cc98
4 files changed, 252 insertions, 4 deletions
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp
index 67cd8c1..0d3b3d0 100644
--- a/gfx/gfx.gyp
+++ b/gfx/gfx.gyp
@@ -30,6 +30,7 @@
'insets_unittest.cc',
'rect_unittest.cc',
'run_all_unittests.cc',
+ 'scoped_image_unittest.cc',
'skbitmap_operations_unittest.cc',
'test_suite.h',
'<(SHARED_INTERMEDIATE_DIR)/gfx/gfx_resources.rc',
@@ -124,6 +125,7 @@
'point.h',
'rect.cc',
'rect.h',
+ 'scoped_image.h',
'scrollbar_size.cc',
'scrollbar_size.h',
'size.cc',
diff --git a/gfx/native_widget_types.h b/gfx/native_widget_types.h
index b7ff4bb..9c85edd 100644
--- a/gfx/native_widget_types.h
+++ b/gfx/native_widget_types.h
@@ -96,12 +96,13 @@ typedef GdkRegion* NativeRegion;
#endif
#if defined(OS_MACOSX)
-typedef NSImage* NativeImage;
-#elif defined(USE_X11) && !defined(TOOLKIT_VIEWS)
-typedef GdkPixbuf* NativeImage;
+typedef NSImage NativeImageType;
+#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
+typedef GdkPixbuf NativeImageType;
#else
-typedef const SkBitmap* NativeImage;
+typedef SkBitmap NativeImageType;
#endif
+typedef NativeImageType* NativeImage;
// Note: for test_shell we're packing a pointer into the NativeViewId. So, if
// you make it a type which is smaller than a pointer, you have to fix
diff --git a/gfx/scoped_image.h b/gfx/scoped_image.h
new file mode 100644
index 0000000..c539a94
--- /dev/null
+++ b/gfx/scoped_image.h
@@ -0,0 +1,147 @@
+// Copyright (c) 2010 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 GFX_SCOPED_IMAGE_H_
+#define GFX_SCOPED_IMAGE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "build/build_config.h"
+#include "gfx/native_widget_types.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+#if defined(OS_LINUX)
+#include <glib-object.h>
+#elif defined(OS_MACOSX)
+#include "base/mac_util.h"
+#endif
+
+namespace gfx {
+
+namespace internal {
+
+// ScopedImage is class that encapsulates one of the three platform-specific
+// images used: SkBitmap, NSImage, and GdkPixbuf. This is the abstract interface
+// that all ScopedImages respond to. This wrapper expects to own the image it
+// holds, unless it is Release()ed or Free()ed.
+//
+// This class is abstract and callers should use the specialized versions below,
+// which are not in the internal namespace.
+template <class ImageType>
+class ScopedImage {
+ public:
+ virtual ~ScopedImage() {}
+
+ // Frees the actual image that this boxes.
+ virtual void Free() = 0;
+
+ // Returns the image that this boxes.
+ ImageType* Get() {
+ return image_;
+ }
+
+ // Frees the current image and sets a new one.
+ void Set(ImageType* new_image) {
+ Free();
+ image_ = new_image;
+ }
+
+ // Returns the image this boxes and relinquishes ownership.
+ ImageType* Release() {
+ ImageType* tmp = image_;
+ image_ = NULL;
+ return tmp;
+ }
+
+ protected:
+ explicit ScopedImage(ImageType* image) : image_(image) {}
+ ImageType* image_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedImage);
+};
+
+} // namespace internal
+
+// Generic template.
+template <class ImageType = gfx::NativeImageType>
+class ScopedImage : public gfx::internal::ScopedImage<ImageType> {
+ public:
+ explicit ScopedImage(gfx::NativeImage image)
+ : gfx::internal::ScopedImage<ImageType>(image) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedImage<ImageType>);
+};
+
+// Specialization for SkBitmap on all platforms.
+template <>
+class ScopedImage<SkBitmap> : public gfx::internal::ScopedImage<SkBitmap> {
+ public:
+ explicit ScopedImage(SkBitmap* image)
+ : gfx::internal::ScopedImage<SkBitmap>(image) {}
+ virtual ~ScopedImage() {
+ Free();
+ }
+
+ virtual void Free() {
+ delete image_;
+ image_ = NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedImage);
+};
+
+// Specialization for the NSImage type on Mac OS X.
+#if defined(OS_MACOSX)
+template <>
+class ScopedImage<NSImage> : public gfx::internal::ScopedImage<NSImage> {
+ public:
+ explicit ScopedImage(NSImage* image)
+ : gfx::internal::ScopedImage<NSImage>(image) {}
+ virtual ~ScopedImage() {
+ Free();
+ }
+
+ virtual void Free() {
+ mac_util::NSObjectRelease(image_);
+ image_ = NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedImage);
+};
+#endif // defined(OS_MACOSX)
+
+// Specialization for the GdkPixbuf type on Linux.
+#if defined(OS_LINUX)
+template <>
+class ScopedImage<GdkPixbuf> : public gfx::internal::ScopedImage<GdkPixbuf> {
+ public:
+ explicit ScopedImage(GdkPixbuf* image)
+ : gfx::internal::ScopedImage<GdkPixbuf>(image) {}
+ virtual ~ScopedImage() {
+ Free();
+ }
+
+ virtual void Free() {
+ if (image_) {
+ g_object_unref(image_);
+ image_ = NULL;
+ }
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedImage);
+};
+#endif // defined(OS_LINUX)
+
+// Typedef ScopedNativeImage to the default template argument. This allows for
+// easy exchange between gfx::NativeImage and a gfx::ScopedNativeImage.
+typedef ScopedImage<> ScopedNativeImage;
+
+} // namespace gfx
+
+#endif // GFX_SCOPED_IMAGE_H_
diff --git a/gfx/scoped_image_unittest.cc b/gfx/scoped_image_unittest.cc
new file mode 100644
index 0000000..c43dd43
--- /dev/null
+++ b/gfx/scoped_image_unittest.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2010 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.
+
+#include "base/scoped_ptr.h"
+#include "gfx/scoped_image.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+#if defined(OS_LINUX)
+#include "gfx/gtk_util.h"
+#elif defined(OS_MACOSX)
+#include "base/mac_util.h"
+#include "skia/ext/skia_utils_mac.h"
+#endif
+
+namespace {
+
+class ScopedImageTest : public testing::Test {
+ public:
+ SkBitmap* CreateBitmap() {
+ SkBitmap* bitmap = new SkBitmap();
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, 25, 25);
+ bitmap->allocPixels();
+ bitmap->eraseRGB(255, 0, 0);
+ return bitmap;
+ }
+
+ gfx::NativeImage CreateNativeImage() {
+ scoped_ptr<SkBitmap> bitmap(CreateBitmap());
+#if defined(OS_MACOSX)
+ NSImage* image = gfx::SkBitmapToNSImage(*(bitmap.get()));
+ mac_util::NSObjectRetain(image);
+ return image;
+#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
+ return gfx::GdkPixbufFromSkBitmap(bitmap.get());
+#else
+ return bitmap.release();
+#endif
+ }
+};
+
+TEST_F(ScopedImageTest, Initialize) {
+ gfx::ScopedImage<SkBitmap> image(CreateBitmap());
+ EXPECT_TRUE(image.Get());
+}
+
+TEST_F(ScopedImageTest, Free) {
+ gfx::ScopedImage<SkBitmap> image(CreateBitmap());
+ EXPECT_TRUE(image.Get());
+ image.Free();
+ EXPECT_FALSE(image.Get());
+}
+
+TEST_F(ScopedImageTest, Release) {
+ gfx::ScopedImage<SkBitmap> image(CreateBitmap());
+ EXPECT_TRUE(image.Get());
+ scoped_ptr<SkBitmap> bitmap(image.Release());
+ EXPECT_FALSE(image.Get());
+}
+
+TEST_F(ScopedImageTest, Set) {
+ gfx::ScopedImage<SkBitmap> image(CreateBitmap());
+ EXPECT_TRUE(image.Get());
+ SkBitmap* image2 = CreateBitmap();
+ image.Set(image2);
+ EXPECT_EQ(image2, image.Get());
+}
+
+TEST_F(ScopedImageTest, NativeInitialize) {
+ gfx::ScopedNativeImage image(CreateNativeImage());
+ EXPECT_TRUE(image.Get());
+}
+
+TEST_F(ScopedImageTest, NativeFree) {
+ gfx::ScopedNativeImage image(CreateNativeImage());
+ EXPECT_TRUE(image.Get());
+ image.Free();
+ EXPECT_FALSE(image.Get());
+}
+
+TEST_F(ScopedImageTest, NativeRelease) {
+ gfx::ScopedNativeImage image(CreateNativeImage());
+ EXPECT_TRUE(image.Get());
+ gfx::ScopedNativeImage image2(image.Release());
+ EXPECT_FALSE(image.Get());
+ EXPECT_TRUE(image2.Get());
+}
+
+TEST_F(ScopedImageTest, NativeSet) {
+ gfx::ScopedNativeImage image(CreateNativeImage());
+ EXPECT_TRUE(image.Get());
+ gfx::NativeImage image2 = CreateNativeImage();
+ image.Set(image2);
+ EXPECT_EQ(image2, image.Get());
+}
+
+} // namespace