OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file implements the ViewGLContext and PbufferGLContext classes. | 5 // This file implements the ViewGLContext and PbufferGLContext classes. |
6 | 6 |
7 #include <GL/glew.h> | |
8 #include <GL/osmew.h> | |
9 #include <OpenGL/OpenGL.h> | 7 #include <OpenGL/OpenGL.h> |
10 | 8 |
11 #include "app/surface/accelerated_surface_mac.h" | 9 #include "app/surface/accelerated_surface_mac.h" |
12 #include "base/logging.h" | 10 #include "base/logging.h" |
13 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 #include "app/gfx/gl/gl_bindings.h" |
14 #include "app/gfx/gl/gl_context.h" | 13 #include "app/gfx/gl/gl_context.h" |
15 #include "app/gfx/gl/gl_context_osmesa.h" | 14 #include "app/gfx/gl/gl_context_stub.h" |
| 15 #include "app/gfx/gl/gl_implementation.h" |
16 | 16 |
17 namespace gfx { | 17 namespace gfx { |
18 | 18 |
19 typedef CGLContextObj GLContextHandle; | 19 typedef CGLContextObj GLContextHandle; |
20 typedef CGLPBufferObj PbufferHandle; | 20 typedef CGLPBufferObj PbufferHandle; |
21 | 21 |
22 // This class is a wrapper around a GL context used for offscreen rendering. | 22 // This class is a wrapper around a GL context used for offscreen rendering. |
23 // It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful | 23 // It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful |
24 // rendering. | 24 // rendering. |
25 class PbufferGLContext : public GLContext { | 25 class PbufferGLContext : public GLContext { |
26 public: | 26 public: |
27 PbufferGLContext() | 27 PbufferGLContext() |
28 : context_(NULL), | 28 : context_(NULL), |
29 pbuffer_(NULL) { | 29 pbuffer_(NULL) { |
30 } | 30 } |
31 | 31 |
32 // Initializes the GL context. | 32 // Initializes the GL context. |
33 bool Initialize(void* shared_handle); | 33 bool Initialize(GLContext* shared_context); |
34 | 34 |
35 virtual void Destroy(); | 35 virtual void Destroy(); |
36 virtual bool MakeCurrent(); | 36 virtual bool MakeCurrent(); |
37 virtual bool IsCurrent(); | 37 virtual bool IsCurrent(); |
38 virtual bool IsOffscreen(); | 38 virtual bool IsOffscreen(); |
39 virtual void SwapBuffers(); | 39 virtual void SwapBuffers(); |
40 virtual gfx::Size GetSize(); | 40 virtual gfx::Size GetSize(); |
41 virtual void* GetHandle(); | 41 virtual void* GetHandle(); |
42 | 42 |
43 private: | 43 private: |
44 GLContextHandle context_; | 44 GLContextHandle context_; |
45 PbufferHandle pbuffer_; | 45 PbufferHandle pbuffer_; |
46 | 46 |
47 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); | 47 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); |
48 }; | 48 }; |
49 | 49 |
50 static bool InitializeOneOff() { | 50 static bool InitializeOneOff() { |
51 static bool initialized = false; | 51 static bool initialized = false; |
52 if (initialized) | 52 if (initialized) |
53 return true; | 53 return true; |
54 | 54 |
55 osmewInit(); | 55 if (!InitializeGLBindings(kGLImplementationDesktopGL)) { |
| 56 LOG(ERROR) << "Could not initialize GL."; |
| 57 return false; |
| 58 } |
| 59 |
56 initialized = true; | 60 initialized = true; |
57 return true; | 61 return true; |
58 } | 62 } |
59 | 63 |
60 bool PbufferGLContext::Initialize(void* shared_handle) { | 64 bool PbufferGLContext::Initialize(GLContext* shared_context) { |
61 // Create a 1x1 pbuffer and associated context to bootstrap things. | 65 // Create a 1x1 pbuffer and associated context to bootstrap things. |
62 static const CGLPixelFormatAttribute attribs[] = { | 66 static const CGLPixelFormatAttribute attribs[] = { |
63 (CGLPixelFormatAttribute) kCGLPFAPBuffer, | 67 (CGLPixelFormatAttribute) kCGLPFAPBuffer, |
64 (CGLPixelFormatAttribute) 0 | 68 (CGLPixelFormatAttribute) 0 |
65 }; | 69 }; |
66 CGLPixelFormatObj pixel_format; | 70 CGLPixelFormatObj pixel_format; |
67 GLint num_pixel_formats; | 71 GLint num_pixel_formats; |
68 if (CGLChoosePixelFormat(attribs, | 72 if (CGLChoosePixelFormat(attribs, |
69 &pixel_format, | 73 &pixel_format, |
70 &num_pixel_formats) != kCGLNoError) { | 74 &num_pixel_formats) != kCGLNoError) { |
71 DLOG(ERROR) << "Error choosing pixel format."; | 75 DLOG(ERROR) << "Error choosing pixel format."; |
72 Destroy(); | 76 Destroy(); |
73 return false; | 77 return false; |
74 } | 78 } |
75 if (!pixel_format) { | 79 if (!pixel_format) { |
76 return false; | 80 return false; |
77 } | 81 } |
78 CGLError res = CGLCreateContext(pixel_format, | 82 |
79 static_cast<GLContextHandle>(shared_handle), | 83 GLContextHandle shared_handle = NULL; |
80 &context_); | 84 if (shared_context) |
| 85 shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle()); |
| 86 |
| 87 CGLError res = CGLCreateContext(pixel_format, shared_handle, &context_); |
81 CGLDestroyPixelFormat(pixel_format); | 88 CGLDestroyPixelFormat(pixel_format); |
82 if (res != kCGLNoError) { | 89 if (res != kCGLNoError) { |
83 DLOG(ERROR) << "Error creating context."; | 90 DLOG(ERROR) << "Error creating context."; |
84 Destroy(); | 91 Destroy(); |
85 return false; | 92 return false; |
86 } | 93 } |
87 if (CGLCreatePBuffer(1, 1, | 94 if (CGLCreatePBuffer(1, 1, |
88 GL_TEXTURE_2D, GL_RGBA, | 95 GL_TEXTURE_2D, GL_RGBA, |
89 0, &pbuffer_) != kCGLNoError) { | 96 0, &pbuffer_) != kCGLNoError) { |
90 DLOG(ERROR) << "Error creating pbuffer."; | 97 DLOG(ERROR) << "Error creating pbuffer."; |
91 Destroy(); | 98 Destroy(); |
92 return false; | 99 return false; |
93 } | 100 } |
94 if (CGLSetPBuffer(context_, pbuffer_, 0, 0, 0) != kCGLNoError) { | 101 if (CGLSetPBuffer(context_, pbuffer_, 0, 0, 0) != kCGLNoError) { |
95 DLOG(ERROR) << "Error attaching pbuffer to context."; | 102 DLOG(ERROR) << "Error attaching pbuffer to context."; |
96 Destroy(); | 103 Destroy(); |
97 return false; | 104 return false; |
98 } | 105 } |
99 | 106 |
100 if (!MakeCurrent()) { | 107 if (!MakeCurrent()) { |
101 Destroy(); | 108 Destroy(); |
102 DLOG(ERROR) << "Couldn't make context current for initialization."; | 109 DLOG(ERROR) << "Couldn't make context current for initialization."; |
103 return false; | 110 return false; |
104 } | 111 } |
105 | 112 |
106 if (!InitializeGLEW()) { | |
107 Destroy(); | |
108 return false; | |
109 } | |
110 | |
111 if (!InitializeCommon()) { | 113 if (!InitializeCommon()) { |
112 Destroy(); | 114 Destroy(); |
113 return false; | 115 return false; |
114 } | 116 } |
115 | 117 |
116 return true; | 118 return true; |
117 } | 119 } |
118 | 120 |
119 void PbufferGLContext::Destroy() { | 121 void PbufferGLContext::Destroy() { |
120 if (context_) { | 122 if (context_) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 | 155 |
154 gfx::Size PbufferGLContext::GetSize() { | 156 gfx::Size PbufferGLContext::GetSize() { |
155 NOTREACHED() << "Should not be requesting size of a PbufferGLContext."; | 157 NOTREACHED() << "Should not be requesting size of a PbufferGLContext."; |
156 return gfx::Size(1, 1); | 158 return gfx::Size(1, 1); |
157 } | 159 } |
158 | 160 |
159 void* PbufferGLContext::GetHandle() { | 161 void* PbufferGLContext::GetHandle() { |
160 return context_; | 162 return context_; |
161 } | 163 } |
162 | 164 |
163 GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { | 165 GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { |
164 if (!InitializeOneOff()) | 166 if (!InitializeOneOff()) |
165 return NULL; | 167 return NULL; |
166 | 168 |
167 if (OSMesaCreateContext) { | 169 switch (GetGLImplementation()) { |
168 scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); | 170 case kGLImplementationDesktopGL: { |
| 171 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); |
| 172 if (!context->Initialize(shared_context)) |
| 173 return NULL; |
169 | 174 |
170 if (!context->Initialize(shared_handle)) | 175 return context.release(); |
| 176 } |
| 177 case kGLImplementationMockGL: |
| 178 return new StubGLContext; |
| 179 default: |
| 180 NOTREACHED(); |
171 return NULL; | 181 return NULL; |
172 | |
173 return context.release(); | |
174 } else { | |
175 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); | |
176 if (!context->Initialize(shared_handle)) | |
177 return NULL; | |
178 | |
179 return context.release(); | |
180 } | 182 } |
181 } | 183 } |
182 | 184 |
183 } // namespace gfx | 185 } // namespace gfx |
OLD | NEW |