Exclude TrayIMETest.PerformActionOnDetailedView under valgrind, where it crashes.
[chromium-blink-merge.git] / ui / gl / gl_context_osmesa.cc
blobee0f7570ebc047bb799bbdf81ea453516e685e12
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.
5 #include "ui/gl/gl_context_osmesa.h"
7 #include <GL/osmesa.h>
9 #include "base/logging.h"
10 #include "ui/gfx/geometry/size.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_surface.h"
14 namespace gfx {
16 GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group)
17 : GLContextReal(share_group),
18 context_(nullptr),
19 is_released_(false) {
22 bool GLContextOSMesa::Initialize(GLSurface* compatible_surface,
23 GpuPreference gpu_preference) {
24 DCHECK(!context_);
26 OSMesaContext share_handle = static_cast<OSMesaContext>(
27 share_group() ? share_group()->GetHandle() : nullptr);
29 GLuint format = compatible_surface->GetFormat();
30 DCHECK_NE(format, (unsigned)0);
31 context_ = OSMesaCreateContextExt(format,
32 0, // depth bits
33 0, // stencil bits
34 0, // accum bits
35 share_handle);
36 if (!context_) {
37 LOG(ERROR) << "OSMesaCreateContextExt failed.";
38 return false;
41 return true;
44 void GLContextOSMesa::Destroy() {
45 if (context_) {
46 OSMesaDestroyContext(static_cast<OSMesaContext>(context_));
47 context_ = nullptr;
51 bool GLContextOSMesa::MakeCurrent(GLSurface* surface) {
52 DCHECK(context_);
54 gfx::Size size = surface->GetSize();
56 ScopedReleaseCurrent release_current;
57 if (!OSMesaMakeCurrent(context_,
58 surface->GetHandle(),
59 GL_UNSIGNED_BYTE,
60 size.width(),
61 size.height())) {
62 LOG(ERROR) << "OSMesaMakeCurrent failed.";
63 Destroy();
64 return false;
66 // Track that we're no longer in a released state to workaround a mesa issue.
67 is_released_ = false;
69 // Set this as soon as the context is current, since we might call into GL.
70 SetRealGLApi();
72 // Row 0 is at the top.
73 OSMesaPixelStore(OSMESA_Y_UP, 0);
75 SetCurrent(surface);
76 if (!InitializeDynamicBindings()) {
77 return false;
80 if (!surface->OnMakeCurrent(this)) {
81 LOG(ERROR) << "Could not make current.";
82 return false;
85 release_current.Cancel();
86 return true;
89 void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) {
90 if (!IsCurrent(surface))
91 return;
93 SetCurrent(nullptr);
95 // Calling |OSMesaMakeCurrent| with nullptr here does not work to release the
96 // context. As a workaround, keep track of the release state, so that we can
97 // correctly determine the state of |IsCurrent|.
98 is_released_ = true;
99 OSMesaMakeCurrent(nullptr, nullptr, GL_UNSIGNED_BYTE, 0, 0);
102 bool GLContextOSMesa::IsCurrent(GLSurface* surface) {
103 DCHECK(context_);
105 // |OSMesaGetCurrentContext| doesn't correctly return nullptr when we release,
106 // check the tracked |is_released_|. See |ReleaseCurrent|.
107 bool native_context_is_current = !is_released_ &&
108 context_ == OSMesaGetCurrentContext();
110 // If our context is current then our notion of which GLContext is
111 // current must be correct. On the other hand, third-party code
112 // using OpenGL might change the current context.
113 DCHECK(!native_context_is_current || (GetRealCurrent() == this));
115 if (!native_context_is_current)
116 return false;
118 if (surface) {
119 GLint width;
120 GLint height;
121 GLint format;
122 void* buffer = nullptr;
123 OSMesaGetColorBuffer(context_, &width, &height, &format, &buffer);
124 if (buffer != surface->GetHandle())
125 return false;
128 return true;
131 void* GLContextOSMesa::GetHandle() {
132 return context_;
135 void GLContextOSMesa::OnSetSwapInterval(int interval) {
136 DCHECK(IsCurrent(nullptr));
139 GLContextOSMesa::~GLContextOSMesa() {
140 Destroy();
143 } // namespace gfx