mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
135 lines
3.3 KiB
C++
135 lines
3.3 KiB
C++
// 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 <GL/osmesa.h>
|
|
|
|
#include "base/logging.h"
|
|
#include "ui/gfx/geometry/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<OSMesaContext>(
|
|
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<OSMesaContext>(context_));
|
|
context_ = NULL;
|
|
}
|
|
}
|
|
|
|
bool GLContextOSMesa::MakeCurrent(GLSurface* surface) {
|
|
DCHECK(context_);
|
|
|
|
gfx::Size size = surface->GetSize();
|
|
|
|
ScopedReleaseCurrent release_current;
|
|
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 (!InitializeDynamicBindings()) {
|
|
return false;
|
|
}
|
|
|
|
if (!surface->OnMakeCurrent(this)) {
|
|
LOG(ERROR) << "Could not make current.";
|
|
return false;
|
|
}
|
|
|
|
release_current.Cancel();
|
|
return true;
|
|
}
|
|
|
|
void GLContextOSMesa::ReleaseCurrent(GLSurface* surface) {
|
|
if (!IsCurrent(surface))
|
|
return;
|
|
|
|
SetCurrent(NULL);
|
|
// TODO: Calling with NULL here does not work to release the context.
|
|
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::OnSetSwapInterval(int interval) {
|
|
DCHECK(IsCurrent(NULL));
|
|
}
|
|
|
|
GLContextOSMesa::~GLContextOSMesa() {
|
|
Destroy();
|
|
}
|
|
|
|
} // namespace gfx
|