- add sources.
[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   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
85 void 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
93 bool 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
120 void* GLContextOSMesa::GetHandle() {
121   return context_;
122 }
123
124 void GLContextOSMesa::SetSwapInterval(int interval) {
125   DCHECK(IsCurrent(NULL));
126 }
127
128 GLContextOSMesa::~GLContextOSMesa() {
129   Destroy();
130 }
131
132 }  // namespace gfx