15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "third_party/mesa/src/include/GL/osmesa.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface_osmesa.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gl/scoped_make_current.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)GLSurfaceOSMesa::GLSurfaceOSMesa(OSMesaSurfaceFormat format, 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const gfx::Size& size) 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : size_(size) { 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) switch (format) { 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case OSMesaSurfaceFormatBGRA: 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) format_ = OSMESA_BGRA; 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case OSMesaSurfaceFormatRGBA: 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) format_ = OSMESA_RGBA; 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Implementations of OSMesa surface do not support having a 0 size. In such 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // cases use a (1, 1) surface. 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (size_.GetArea() == 0) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_.SetSize(1, 1); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceOSMesa::Initialize() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Resize(size_); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLSurfaceOSMesa::Destroy() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceOSMesa::Resize(const gfx::Size& new_size) { 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLContext* current_context = GLContext::GetCurrent(); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool was_current = 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_context && current_context->IsCurrent(this); 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (was_current) { 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_make_current.reset( 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ui::ScopedMakeCurrent(current_context, this)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_context->ReleaseCurrent(this); 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preserve the old buffer. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<int32[]> old_buffer(buffer_.release()); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a new one. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(new int32[new_size.GetArea()]); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(buffer_.get(), 0, new_size.GetArea() * sizeof(buffer_[0])); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the old back buffer into the new buffer. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_buffer.get()) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int copy_width = std::min(size_.width(), new_size.width()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int copy_height = std::min(size_.height(), new_size.height()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < copy_height; ++y) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < copy_width; ++x) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_[y * new_size.width() + x] = old_buffer[y * size_.width() + x]; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = new_size; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceOSMesa::IsOffscreen() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceOSMesa::SwapBuffers() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Should not call SwapBuffers on an GLSurfaceOSMesa."; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size GLSurfaceOSMesa::GetSize() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GLSurfaceOSMesa::GetHandle() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_.get(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned GLSurfaceOSMesa::GetFormat() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return format_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceOSMesa::~GLSurfaceOSMesa() { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool GLSurfaceOSMesaHeadless::IsOffscreen() { return false; } 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool GLSurfaceOSMesaHeadless::SwapBuffers() { return true; } 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 102effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochGLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless() 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, gfx::Size(1, 1)) { 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 106effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochGLSurfaceOSMesaHeadless::~GLSurfaceOSMesaHeadless() { Destroy(); } 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 109