summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-10 13:07:39 +0000
committerccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-10 13:07:39 +0000
commit59878c08d87bd88bc3081d004b93c0e0cd43632c (patch)
treeb9d5513b306bd73cd123944f4cb11f70fc628d15
parentd7210248e3fc78afcb829dad2170023be10438c6 (diff)
downloadchromium_src-59878c08d87bd88bc3081d004b93c0e0cd43632c.zip
chromium_src-59878c08d87bd88bc3081d004b93c0e0cd43632c.tar.gz
chromium_src-59878c08d87bd88bc3081d004b93c0e0cd43632c.tar.bz2
Add helpers for CGL types.
Add base::ScopedTypeRef, which is similar to ScopedCFTypeRef, but allows for parameterized retain and release functions. This is necessary for types such as CGLContextObj, which have their own retain and release methods (and for which calling CFRelease will result in crashes). Add some common typedefs of ScopedTypeRef to cgl_util in ui, along with a scoped CGLContextObj make-current class. BUG=245900 R=thakis@chromium.org,mark@chromium.org TBR=garykac@chromium.org Review URL: https://codereview.chromium.org/157063002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250077 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base.gypi1
-rw-r--r--base/mac/scoped_cftyperef.h85
-rw-r--r--base/mac/scoped_typeref.h132
-rw-r--r--remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm1
-rw-r--r--ui/gl/gl.gyp2
-rw-r--r--ui/gl/scoped_cgl.cc21
-rw-r--r--ui/gl/scoped_cgl.h56
7 files changed, 231 insertions, 67 deletions
diff --git a/base/base.gypi b/base/base.gypi
index 2d3a01d..29e8e46 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -295,6 +295,7 @@
'mac/scoped_nsobject.h',
'mac/scoped_sending_event.h',
'mac/scoped_sending_event.mm',
+ 'mac/scoped_typeref.h',
'mac/sdk_forward_declarations.h',
'macros.h',
'md5.cc',
diff --git a/base/mac/scoped_cftyperef.h b/base/mac/scoped_cftyperef.h
index c41de80..8567f85 100644
--- a/base/mac/scoped_cftyperef.h
+++ b/base/mac/scoped_cftyperef.h
@@ -7,9 +7,7 @@
#include <CoreFoundation/CoreFoundation.h>
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_policy.h"
+#include "base/mac/scoped_typeref.h"
namespace base {
@@ -27,78 +25,33 @@ namespace base {
// then ScopedCFTypeRef<> will call CFRetain() on the object, and the initial
// ownership is not changed.
+namespace internal {
+
+struct ScopedCFTypeRefTraits {
+ static void Retain(CFTypeRef object) {
+ CFRetain(object);
+ }
+ static void Release(CFTypeRef object) {
+ CFRelease(object);
+ }
+};
+
+} // namespace internal
+
template<typename CFT>
-class ScopedCFTypeRef {
+class ScopedCFTypeRef
+ : public ScopedTypeRef<CFT, internal::ScopedCFTypeRefTraits> {
public:
typedef CFT element_type;
explicit ScopedCFTypeRef(
CFT object = NULL,
base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME)
- : object_(object) {
- if (object_ && policy == base::scoped_policy::RETAIN)
- CFRetain(object_);
- }
+ : ScopedTypeRef<CFT,
+ internal::ScopedCFTypeRefTraits>(object, policy) {}
ScopedCFTypeRef(const ScopedCFTypeRef<CFT>& that)
- : object_(that.object_) {
- if (object_)
- CFRetain(object_);
- }
-
- ~ScopedCFTypeRef() {
- if (object_)
- CFRelease(object_);
- }
-
- ScopedCFTypeRef& operator=(const ScopedCFTypeRef<CFT>& that) {
- reset(that.get(), base::scoped_policy::RETAIN);
- return *this;
- }
-
- void reset(CFT object = NULL,
- base::scoped_policy::OwnershipPolicy policy =
- base::scoped_policy::ASSUME) {
- if (object && policy == base::scoped_policy::RETAIN)
- CFRetain(object);
- if (object_)
- CFRelease(object_);
- object_ = object;
- }
-
- bool operator==(CFT that) const {
- return object_ == that;
- }
-
- bool operator!=(CFT that) const {
- return object_ != that;
- }
-
- operator CFT() const {
- return object_;
- }
-
- CFT get() const {
- return object_;
- }
-
- void swap(ScopedCFTypeRef& that) {
- CFT temp = that.object_;
- that.object_ = object_;
- object_ = temp;
- }
-
- // ScopedCFTypeRef<>::release() is like scoped_ptr<>::release. It is NOT
- // a wrapper for CFRelease(). To force a ScopedCFTypeRef<> object to call
- // CFRelease(), use ScopedCFTypeRef<>::reset().
- CFT release() WARN_UNUSED_RESULT {
- CFT temp = object_;
- object_ = NULL;
- return temp;
- }
-
- private:
- CFT object_;
+ : ScopedTypeRef<CFT, internal::ScopedCFTypeRefTraits>(that) {}
};
} // namespace base
diff --git a/base/mac/scoped_typeref.h b/base/mac/scoped_typeref.h
new file mode 100644
index 0000000..61ee311
--- /dev/null
+++ b/base/mac/scoped_typeref.h
@@ -0,0 +1,132 @@
+// Copyright 2014 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 BASE_MAC_SCOPED_TYPEREF_H_
+#define BASE_MAC_SCOPED_TYPEREF_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/scoped_policy.h"
+
+namespace base {
+
+// ScopedTypeRef<> is patterned after scoped_ptr<>, but maintains a ownership
+// of a reference to any type that is maintained by Retain and Release methods.
+//
+// The Traits structure must provide the Retain and Release methods for type T.
+// A default ScopedTypeRefTraits is used but not defined, and should be defined
+// for each type to use this interface. For example, an appropriate definition
+// of ScopedTypeRefTraits for CGLContextObj would be:
+//
+// template<>
+// struct ScopedTypeRefTraits<CGLContextObj> {
+// void Retain(CGLContextObj object) { CGLContextRetain(object); }
+// void Release(CGLContextObj object) { CGLContextRelease(object); }
+// };
+//
+// For the many types that have pass-by-pointer create functions, the function
+// InitializeInto() is provided to allow direct initialization and assumption
+// of ownership of the object. For example, continuing to use the above
+// CGLContextObj specialization:
+//
+// base::ScopedTypeRef<CGLContextObj> context;
+// CGLCreateContext(pixel_format, share_group, context.InitializeInto());
+//
+// For initialization with an existing object, the caller may specify whether
+// the ScopedTypeRef<> being initialized is assuming the caller's existing
+// ownership of the object (and should not call Retain in initialization) or if
+// it should not assume this ownership and must create its own (by calling
+// Retain in initialization). This behavior is based on the |policy| parameter,
+// with |ASSUME| for the former and |RETAIN| for the latter. The default policy
+// is to |ASSUME|.
+
+template<typename T>
+struct ScopedTypeRefTraits;
+
+template<typename T, typename Traits = ScopedTypeRefTraits<T>>
+class ScopedTypeRef {
+ public:
+ typedef T element_type;
+
+ ScopedTypeRef(
+ T object = NULL,
+ base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME)
+ : object_(object) {
+ if (object_ && policy == base::scoped_policy::RETAIN)
+ Traits::Retain(object_);
+ }
+
+ ScopedTypeRef(const ScopedTypeRef<T, Traits>& that)
+ : object_(that.object_) {
+ if (object_)
+ Traits::Retain(object_);
+ }
+
+ ~ScopedTypeRef() {
+ if (object_)
+ Traits::Release(object_);
+ }
+
+ ScopedTypeRef& operator=(const ScopedTypeRef<T, Traits>& that) {
+ reset(that.get(), base::scoped_policy::RETAIN);
+ return *this;
+ }
+
+ // This is to be used only to take ownership of objects that are created
+ // by pass-by-pointer create functions. To enforce this, require that the
+ // object be reset to NULL before this may be used.
+ T* InitializeInto() WARN_UNUSED_RESULT {
+ DCHECK(!object_);
+ return &object_;
+ }
+
+ void reset(T object = NULL,
+ base::scoped_policy::OwnershipPolicy policy =
+ base::scoped_policy::ASSUME) {
+ if (object && policy == base::scoped_policy::RETAIN)
+ Traits::Retain(object);
+ if (object_)
+ Traits::Release(object_);
+ object_ = object;
+ }
+
+ bool operator==(T that) const {
+ return object_ == that;
+ }
+
+ bool operator!=(T that) const {
+ return object_ != that;
+ }
+
+ operator T() const {
+ return object_;
+ }
+
+ T get() const {
+ return object_;
+ }
+
+ void swap(ScopedTypeRef& that) {
+ T temp = that.object_;
+ that.object_ = object_;
+ object_ = temp;
+ }
+
+ // ScopedTypeRef<>::release() is like scoped_ptr<>::release. It is NOT
+ // a wrapper for Release(). To force a ScopedTypeRef<> object to call
+ // Release(), use ScopedTypeRef<>::reset().
+ T release() WARN_UNUSED_RESULT {
+ T temp = object_;
+ object_ = NULL;
+ return temp;
+ }
+
+ private:
+ T object_;
+};
+
+} // namespace base
+
+#endif // BASE_MAC_SCOPED_TYPEREF_H_
diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm b/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm
index a90adf8..00878cf 100644
--- a/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm
+++ b/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm
@@ -6,7 +6,6 @@
#import <Cocoa/Cocoa.h>
-#include "base/mac/scoped_cftyperef.h"
#include "remoting/host/installer/mac/uninstaller/remoting_uninstaller.h"
@implementation RemotingUninstallerAppDelegate
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 7374c86..5f9685a 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -260,6 +260,8 @@
'gl_context_nsview.h',
'gl_surface_nsview.mm',
'gl_surface_nsview.h',
+ 'scoped_cgl.cc',
+ 'scoped_cgl.h',
],
'link_settings': {
'libraries': [
diff --git a/ui/gl/scoped_cgl.cc b/ui/gl/scoped_cgl.cc
new file mode 100644
index 0000000..9fef385
--- /dev/null
+++ b/ui/gl/scoped_cgl.cc
@@ -0,0 +1,21 @@
+// Copyright 2014 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/logging.h"
+#include "ui/gl/scoped_cgl.h"
+
+namespace gfx {
+
+ScopedCGLSetCurrentContext::ScopedCGLSetCurrentContext(CGLContextObj context)
+ : previous_context_(CGLGetCurrentContext(), base::scoped_policy::RETAIN) {
+ CGLError error = CGLSetCurrentContext(context);
+ DCHECK_EQ(error, kCGLNoError) << "CGLSetCurrentContext should never fail";
+}
+
+ScopedCGLSetCurrentContext::~ScopedCGLSetCurrentContext() {
+ CGLError error = CGLSetCurrentContext(previous_context_);
+ DCHECK_EQ(error, kCGLNoError) << "CGLSetCurrentContext should never fail";
+}
+
+} // namespace gfx
diff --git a/ui/gl/scoped_cgl.h b/ui/gl/scoped_cgl.h
new file mode 100644
index 0000000..81e1e6e
--- /dev/null
+++ b/ui/gl/scoped_cgl.h
@@ -0,0 +1,56 @@
+// Copyright 2014 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 UI_GL_SCOPED_CGL_H_
+#define UI_GL_SCOPED_CGL_H_
+
+#include <OpenGL/OpenGL.h>
+
+#include "base/mac/scoped_typeref.h"
+#include "ui/gl/gl_export.h"
+
+namespace base {
+
+template<>
+struct ScopedTypeRefTraits<CGLContextObj> {
+ static void Retain(CGLContextObj object) {
+ CGLRetainContext(object);
+ }
+ static void Release(CGLContextObj object) {
+ CGLReleaseContext(object);
+ }
+};
+
+template<>
+struct ScopedTypeRefTraits<CGLPixelFormatObj> {
+ static void Retain(CGLPixelFormatObj object) {
+ CGLRetainPixelFormat(object);
+ }
+ static void Release(CGLPixelFormatObj object) {
+ CGLReleasePixelFormat(object);
+ }
+};
+
+} // namespace base
+
+namespace gfx {
+
+class GL_EXPORT ScopedCGLSetCurrentContext {
+ public:
+ explicit ScopedCGLSetCurrentContext(CGLContextObj context);
+ ~ScopedCGLSetCurrentContext();
+ private:
+ // Note that if a context is destroyed when it is current, then the current
+ // context is changed to NULL. Take out a reference on |previous_context_| to
+ // preserve this behavior (when this falls out of scope, |previous_context_|
+ // will be made current, then released, so NULL will be current if that
+ // release destroys the context).
+ base::ScopedTypeRef<CGLContextObj> previous_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedCGLSetCurrentContext);
+};
+
+} // namespace gfx
+
+#endif // UI_GL_SCOPED_CGL_H_