Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
visual_darwin.mm
Go to the documentation of this file.
1 
18 // File used on only iOS and Mac, which must use a .mm extension to invoke the
19 // objective-c compiler.
20 
21 #include "ion/base/logging.h"
22 #include "ion/portgfx/visual.h"
23 
24 #if defined(ION_PLATFORM_IOS)
25 # include <OpenGLES/EAGL.h>
26 #else
27 # include <AppKit/NSOpenGL.h>
28 #endif
29 
30 namespace ion {
31 namespace portgfx {
32 
33 struct Visual::VisualInfo {
34  // These are defined in visual.cc.
35  static void* GetCurrentContext();
36  static void ClearCurrentContext();
37 
38  VisualInfo() : weakContext(NULL), ownedContext(NULL) {}
39  // Use weak reference for unowned context, strong reference for owned context.
40 #if defined(ION_PLATFORM_IOS)
41  __weak EAGLContext* weakContext;
42  EAGLContext* ownedContext;
43 #else
44  __weak NSOpenGLContext* weakContext;
45  NSOpenGLContext* ownedContext;
46 #endif
47 };
48 
49 #if defined(ION_PLATFORM_IOS)
50 void* Visual::VisualInfo::GetCurrentContext() {
51  return (__bridge void*)[EAGLContext currentContext];
52 }
53 
54 Visual::Visual(Type type)
55  : visual_(new VisualInfo), type_(type) {
56  EAGLContext* current_context = [EAGLContext currentContext];
57 
58  if (type == kCurrent) {
59  // Store a weak reference to contexts we don't own.
60  visual_->weakContext = current_context;
61  MakeCurrent(this);
62  } else {
63  EAGLSharegroup* share_group =
64  (type == kShare && current_context) ? current_context.sharegroup : NULL;
65  // Only store a strong reference to contexts we create and own.
66  visual_->ownedContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
67  sharegroup:share_group];
68  visual_->weakContext = visual_->ownedContext;
69  }
70 }
71 
72 void Visual::VisualInfo::ClearCurrentContext() {
73  [EAGLContext setCurrentContext:nil];
74 }
75 
76 bool Visual::MakeCurrent() const {
77  EAGLContext *strongContext = visual_->weakContext;
78  if (strongContext == nil) {
79  LOG(ERROR) << "Unable to make Visual current. Unowned context has been released.";
80  return false;
81  }
82  const BOOL success = [EAGLContext setCurrentContext:strongContext];
83  if (success == NO) {
84  LOG(ERROR) << "Unable to make Visual current.";
85  return false;
86  } else {
87  return true;
88  }
89 }
90 
91 #else
92 void* Visual::VisualInfo::GetCurrentContext() {
93  return (__bridge void*)[NSOpenGLContext currentContext];
94 }
95 
96 void Visual::VisualInfo::ClearCurrentContext() {
97  [NSOpenGLContext clearCurrentContext];
98 }
99 
100 Visual::Visual(Type type)
101  : visual_(new VisualInfo), type_(type) {
102  // Save the old context.
103  NSOpenGLContext* current_context = [NSOpenGLContext currentContext];
104 
105  if (type == kCurrent) {
106  // Store a weak reference to contexts we don't own.
107  visual_->weakContext = current_context;
108  MakeCurrent(this);
109  } else {
110  NSOpenGLPixelFormatAttribute pixelAttrs[] = {
111  NSOpenGLPFAColorSize, 24,
112  NSOpenGLPFAAlphaSize, 8,
113  NSOpenGLPFADepthSize, 24,
114  NSOpenGLPFAStencilSize, 8,
115  NSOpenGLPFASampleBuffers, 0,
116  0,
117  };
118 
119  NSOpenGLPixelFormat* pixelFormat =
120  [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttrs];
121  NSOpenGLContext* share_context = (type == kShare) ? current_context : NULL;
122  // Only store a strong reference to contexts we create and own.
123  visual_->ownedContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
124  shareContext:share_context];
125  visual_->weakContext = visual_->ownedContext;
126  }
127 }
128 
129 bool Visual::MakeCurrent() const {
130  NSOpenGLContext *strongContext = visual_->weakContext;
131  if (strongContext == nil) {
132  LOG(ERROR) << "Unable to make Visual current. Unowned context has been released.";
133  return false;
134  }
135  [strongContext makeCurrentContext];
136  if (strongContext != [NSOpenGLContext currentContext]) {
137  LOG(ERROR) << "Unable to make Visual current.";
138  return false;
139  } else {
140  return true;
141  }
142 }
143 
144 #endif
145 
146 Visual::Visual() : visual_(new VisualInfo), type_(kMock) {}
147 
148 void Visual::UpdateId() {
149  id_ = reinterpret_cast<size_t>(visual_->weakContext);
150 }
151 
152 bool Visual::IsValid() const {
153  return visual_->weakContext != NULL;
154 }
155 
157  visual_->weakContext = nil;
158  visual_->ownedContext = nil;
159 }
160 
162  visual_->weakContext = nil;
163  visual_->ownedContext = nil;
164 }
165 
166 Visual::~Visual() {
167  TeardownVisual(this);
168 }
169 
170 } // namespace portgfx
171 } // namespace ion
virtual bool IsValid() const
Returns true if the OpenGL initialization was successful.
Definition: visual.cc:949
std::string type
Definition: printer.cc:353
#define LOG(severity)
Logs the streamed message unconditionally with a severity of severity.
Definition: logging.h:216
virtual void UpdateId()
Updates this' ID in a platform dependent way.
Definition: visual.cc:959
Visual()
Constructor for subclasses that make their own contexts.
Definition: visual.cc:948
virtual void TeardownContextNew()
Destroy Visuals of type kNew.
Definition: visual.cc:951
virtual ~Visual()
OpenGL calls should not be made after the Visual is destroyed.
Definition: visual.cc:953
virtual void TeardownContextShared()
Destroy Visuals of type kShare.
Definition: visual.cc:952
Copyright 2016 Google Inc.
virtual bool MakeCurrent() const
Makes this Visual current for this thread and returns whether its associated GL context was successfu...
Definition: visual.cc:950
static void TeardownVisual(Visual *visual)
Responsible for cleaning up |visual's| resources.
Definition: visual.cc:325