Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / gl / gl_context_osmesa.cc
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
14 namespace gfx {
15
16 GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group)
17     : GLContextReal(share_group),
18       context_(NULL) {
19 }
20
21 bool 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
43 void GLContextOSMesa::Destroy() {
44   if (context_) {
45     OSMesaDestroyContext(static_cast<OSMesaContext>(context_));
46     context_ = NULL;
47   }
48 }
49
50 bool GLContextOSMesa::MakeCurrent(GLSurface* surface) {
51   DCHECK(context_);
52
53   gfx::Size size = surface->GetSize();
54
55   ScopedReleaseCurrent release_current;
56   if (!OSMesaMakeCurrent(context_,
57                          surface->GetHandle(),
58                          GL_UNSIGNED_BYTE,
59                          size.width(),
60                          size.height())) {
61     LOG(ERROR) << "OSMesaMakeCurrent failed.";
62     Destroy();
63     return false;
64   }
65
66   // Set this as soon as the context is current, since we might call into GL.
67   SetRealGLApi();
68
69   // Row 0 is at the top.
70   OSMesaPixelStore(OSMESA_Y_UP, 0);
71
72   SetCurrent(surface);
73   if (!InitializeDynamicBindings()) {
74     return false;
75   }
76
77   if (!surface->OnMakeCurrent(this)) {
78     LOG(ERROR) << "Could not make current.";
79     return false;
80   }
81
82   release_current.Cancel();
83   return true;
84 }
85
86 void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) {
87   if (!IsCurrent(surface))
88     return;
89
90   SetCurrent(NULL);
91   // TODO: Calling with NULL here does not work to release the context.
92   OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0);
93 }
94
95 bool GLContextOSMesa::IsCurrent(GLSurface* surface) {
96   DCHECK(context_);
97
98   bool native_context_is_current =
99       context_ == OSMesaGetCurrentContext();
100
101   // If our context is current then our notion of which GLContext is
102   // current must be correct. On the other hand, third-party code
103   // using OpenGL might change the current context.
104   DCHECK(!native_context_is_current || (GetRealCurrent() == this));
105
106   if (!native_context_is_current)
107     return false;
108
109   if (surface) {
110     GLint width;
111     GLint height;
112     GLint format;
113     void* buffer = NULL;
114     OSMesaGetColorBuffer(context_, &width, &height, &format, &buffer);
115     if (buffer != surface->GetHandle())
116       return false;
117   }
118
119   return true;
120 }
121
122 void* GLContextOSMesa::GetHandle() {
123   return context_;
124 }
125
126 void GLContextOSMesa::SetSwapInterval(int interval) {
127   DCHECK(IsCurrent(NULL));
128 }
129
130 GLContextOSMesa::~GLContextOSMesa() {
131   Destroy();
132 }
133
134 }  // namespace gfx