| 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 |