1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/gl/gl_context_osmesa.h" 6 7#include <GL/osmesa.h> 8 9#include "base/logging.h" 10#include "ui/gfx/size.h" 11#include "ui/gl/gl_bindings.h" 12#include "ui/gl/gl_surface.h" 13 14namespace gfx { 15 16GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group) 17 : GLContextReal(share_group), 18 context_(NULL) { 19} 20 21bool GLContextOSMesa::Initialize(GLSurface* compatible_surface, 22 GpuPreference gpu_preference) { 23 DCHECK(!context_); 24 25 OSMesaContext share_handle = static_cast<OSMesaContext>( 26 share_group() ? share_group()->GetHandle() : NULL); 27 28 GLuint format = compatible_surface->GetFormat(); 29 DCHECK_NE(format, (unsigned)0); 30 context_ = OSMesaCreateContextExt(format, 31 0, // depth bits 32 0, // stencil bits 33 0, // accum bits 34 share_handle); 35 if (!context_) { 36 LOG(ERROR) << "OSMesaCreateContextExt failed."; 37 return false; 38 } 39 40 return true; 41} 42 43void GLContextOSMesa::Destroy() { 44 if (context_) { 45 OSMesaDestroyContext(static_cast<OSMesaContext>(context_)); 46 context_ = NULL; 47 } 48} 49 50bool GLContextOSMesa::MakeCurrent(GLSurface* surface) { 51 DCHECK(context_); 52 53 gfx::Size size = surface->GetSize(); 54 55 if (!OSMesaMakeCurrent(context_, 56 surface->GetHandle(), 57 GL_UNSIGNED_BYTE, 58 size.width(), 59 size.height())) { 60 LOG(ERROR) << "OSMesaMakeCurrent failed."; 61 Destroy(); 62 return false; 63 } 64 65 // Set this as soon as the context is current, since we might call into GL. 66 SetRealGLApi(); 67 68 // Row 0 is at the top. 69 OSMesaPixelStore(OSMESA_Y_UP, 0); 70 71 SetCurrent(surface); 72 if (!InitializeExtensionBindings()) { 73 ReleaseCurrent(surface); 74 return false; 75 } 76 77 if (!surface->OnMakeCurrent(this)) { 78 LOG(ERROR) << "Could not make current."; 79 return false; 80 } 81 82 return true; 83} 84 85void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) { 86 if (!IsCurrent(surface)) 87 return; 88 89 SetCurrent(NULL); 90 OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0); 91} 92 93bool GLContextOSMesa::IsCurrent(GLSurface* surface) { 94 DCHECK(context_); 95 96 bool native_context_is_current = 97 context_ == OSMesaGetCurrentContext(); 98 99 // If our context is current then our notion of which GLContext is 100 // current must be correct. On the other hand, third-party code 101 // using OpenGL might change the current context. 102 DCHECK(!native_context_is_current || (GetRealCurrent() == this)); 103 104 if (!native_context_is_current) 105 return false; 106 107 if (surface) { 108 GLint width; 109 GLint height; 110 GLint format; 111 void* buffer = NULL; 112 OSMesaGetColorBuffer(context_, &width, &height, &format, &buffer); 113 if (buffer != surface->GetHandle()) 114 return false; 115 } 116 117 return true; 118} 119 120void* GLContextOSMesa::GetHandle() { 121 return context_; 122} 123 124void GLContextOSMesa::SetSwapInterval(int interval) { 125 DCHECK(IsCurrent(NULL)); 126} 127 128GLContextOSMesa::~GLContextOSMesa() { 129 Destroy(); 130} 131 132} // namespace gfx 133