// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gl/gl_context_osmesa.h" #include #include "base/logging.h" #include "ui/gfx/size.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_surface.h" namespace gfx { GLContextOSMesa::GLContextOSMesa(GLShareGroup* share_group) : GLContextReal(share_group), context_(NULL) { } bool GLContextOSMesa::Initialize(GLSurface* compatible_surface, GpuPreference gpu_preference) { DCHECK(!context_); OSMesaContext share_handle = static_cast( share_group() ? share_group()->GetHandle() : NULL); GLuint format = compatible_surface->GetFormat(); DCHECK_NE(format, (unsigned)0); context_ = OSMesaCreateContextExt(format, 0, // depth bits 0, // stencil bits 0, // accum bits share_handle); if (!context_) { LOG(ERROR) << "OSMesaCreateContextExt failed."; return false; } return true; } void GLContextOSMesa::Destroy() { if (context_) { OSMesaDestroyContext(static_cast(context_)); context_ = NULL; } } bool GLContextOSMesa::MakeCurrent(GLSurface* surface) { DCHECK(context_); gfx::Size size = surface->GetSize(); if (!OSMesaMakeCurrent(context_, surface->GetHandle(), GL_UNSIGNED_BYTE, size.width(), size.height())) { LOG(ERROR) << "OSMesaMakeCurrent failed."; Destroy(); return false; } // Set this as soon as the context is current, since we might call into GL. SetRealGLApi(); // Row 0 is at the top. OSMesaPixelStore(OSMESA_Y_UP, 0); SetCurrent(surface); if (!InitializeExtensionBindings()) { ReleaseCurrent(surface); return false; } if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Could not make current."; return false; } return true; } void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) { if (!IsCurrent(surface)) return; SetCurrent(NULL); OSMesaMakeCurrent(NULL, NULL, GL_UNSIGNED_BYTE, 0, 0); } bool GLContextOSMesa::IsCurrent(GLSurface* surface) { DCHECK(context_); bool native_context_is_current = context_ == OSMesaGetCurrentContext(); // If our context is current then our notion of which GLContext is // current must be correct. On the other hand, third-party code // using OpenGL might change the current context. DCHECK(!native_context_is_current || (GetRealCurrent() == this)); if (!native_context_is_current) return false; if (surface) { GLint width; GLint height; GLint format; void* buffer = NULL; OSMesaGetColorBuffer(context_, &width, &height, &format, &buffer); if (buffer != surface->GetHandle()) return false; } return true; } void* GLContextOSMesa::GetHandle() { return context_; } void GLContextOSMesa::SetSwapInterval(int interval) { DCHECK(IsCurrent(NULL)); } GLContextOSMesa::~GLContextOSMesa() { Destroy(); } } // namespace gfx