blob: 00acc95b29c0760d4fcead57edf8fe6e6f5802ed [file] [log] [blame]
[email protected]1cda0482012-01-25 17:30:071// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ad7bbbd62011-04-22 23:04:372// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ad7bbbd62011-04-22 23:04:375#include "base/logging.h"
mbarbella1ac4ceb2015-02-10 18:30:066#include "base/numerics/safe_math.h"
[email protected]ffcdc9632014-03-27 17:25:237#include "third_party/mesa/src/include/GL/osmesa.h"
[email protected]c9e2cbbb2012-05-12 21:17:278#include "ui/gl/gl_bindings.h"
9#include "ui/gl/gl_context.h"
10#include "ui/gl/gl_surface_osmesa.h"
[email protected]1e9c0c82013-06-06 14:59:2411#include "ui/gl/scoped_make_current.h"
[email protected]ad7bbbd62011-04-22 23:04:3712
13namespace gfx {
14
[email protected]4da882a52014-08-16 08:29:5115GLSurfaceOSMesa::GLSurfaceOSMesa(OSMesaSurfaceFormat format,
16 const gfx::Size& size)
17 : size_(size) {
18 switch (format) {
19 case OSMesaSurfaceFormatBGRA:
20 format_ = OSMESA_BGRA;
21 break;
22 case OSMesaSurfaceFormatRGBA:
23 format_ = OSMESA_RGBA;
24 break;
25 }
[email protected]772aa832014-05-30 01:27:4726 // Implementations of OSMesa surface do not support having a 0 size. In such
27 // cases use a (1, 1) surface.
28 if (size_.GetArea() == 0)
29 size_.SetSize(1, 1);
[email protected]ad7bbbd62011-04-22 23:04:3730}
31
[email protected]1cda0482012-01-25 17:30:0732bool GLSurfaceOSMesa::Initialize() {
33 return Resize(size_);
34}
[email protected]ad7bbbd62011-04-22 23:04:3735
[email protected]1cda0482012-01-25 17:30:0736void GLSurfaceOSMesa::Destroy() {
37 buffer_.reset();
38}
39
40bool GLSurfaceOSMesa::Resize(const gfx::Size& new_size) {
[email protected]1e9c0c82013-06-06 14:59:2441 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
[email protected]f189b252011-12-08 22:30:1442 GLContext* current_context = GLContext::GetCurrent();
[email protected]1e9c0c82013-06-06 14:59:2443 bool was_current =
44 current_context && current_context->IsCurrent(this);
45 if (was_current) {
46 scoped_make_current.reset(
47 new ui::ScopedMakeCurrent(current_context, this));
[email protected]f189b252011-12-08 22:30:1448 current_context->ReleaseCurrent(this);
[email protected]1e9c0c82013-06-06 14:59:2449 }
[email protected]f189b252011-12-08 22:30:1450
[email protected]ffae4022011-05-12 22:54:2951 // Preserve the old buffer.
[email protected]d9251202013-01-16 22:40:0952 scoped_ptr<int32[]> old_buffer(buffer_.release());
[email protected]ad7bbbd62011-04-22 23:04:3753
mbarbella1ac4ceb2015-02-10 18:30:0654 base::CheckedNumeric<int> checked_size = sizeof(buffer_[0]);
55 checked_size *= new_size.width();
56 checked_size *= new_size.height();
57 if (!checked_size.IsValid())
58 return false;
59
[email protected]ffae4022011-05-12 22:54:2960 // Allocate a new one.
[email protected]1cda0482012-01-25 17:30:0761 buffer_.reset(new int32[new_size.GetArea()]);
mbarbella1ac4ceb2015-02-10 18:30:0662 if (!buffer_.get())
63 return false;
64
[email protected]1cda0482012-01-25 17:30:0765 memset(buffer_.get(), 0, new_size.GetArea() * sizeof(buffer_[0]));
[email protected]ffae4022011-05-12 22:54:2966
67 // Copy the old back buffer into the new buffer.
[email protected]1cda0482012-01-25 17:30:0768 if (old_buffer.get()) {
69 int copy_width = std::min(size_.width(), new_size.width());
70 int copy_height = std::min(size_.height(), new_size.height());
71 for (int y = 0; y < copy_height; ++y) {
72 for (int x = 0; x < copy_width; ++x) {
73 buffer_[y * new_size.width() + x] = old_buffer[y * size_.width() + x];
74 }
[email protected]ad7bbbd62011-04-22 23:04:3775 }
76 }
77
[email protected]ad7bbbd62011-04-22 23:04:3778 size_ = new_size;
[email protected]f189b252011-12-08 22:30:1479
[email protected]1b5eee12011-10-26 21:44:1280 return true;
[email protected]ad7bbbd62011-04-22 23:04:3781}
82
[email protected]ad7bbbd62011-04-22 23:04:3783bool GLSurfaceOSMesa::IsOffscreen() {
84 return true;
85}
86
achaulkec8c2db2015-05-29 16:35:0387gfx::SwapResult GLSurfaceOSMesa::SwapBuffers() {
[email protected]ad7bbbd62011-04-22 23:04:3788 NOTREACHED() << "Should not call SwapBuffers on an GLSurfaceOSMesa.";
achaulkec8c2db2015-05-29 16:35:0389 return gfx::SwapResult::SWAP_FAILED;
[email protected]ad7bbbd62011-04-22 23:04:3790}
91
92gfx::Size GLSurfaceOSMesa::GetSize() {
93 return size_;
94}
95
96void* GLSurfaceOSMesa::GetHandle() {
97 return buffer_.get();
98}
99
[email protected]f62a5ab2011-05-23 20:34:15100unsigned GLSurfaceOSMesa::GetFormat() {
101 return format_;
102}
103
[email protected]ab9327c2012-05-02 02:38:08104GLSurfaceOSMesa::~GLSurfaceOSMesa() {
105 Destroy();
106}
107
[email protected]ffcdc9632014-03-27 17:25:23108bool GLSurfaceOSMesaHeadless::IsOffscreen() { return false; }
109
achaulkec8c2db2015-05-29 16:35:03110gfx::SwapResult GLSurfaceOSMesaHeadless::SwapBuffers() {
111 return gfx::SwapResult::SWAP_ACK;
112}
[email protected]ffcdc9632014-03-27 17:25:23113
114GLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless()
[email protected]4da882a52014-08-16 08:29:51115 : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, gfx::Size(1, 1)) {
116}
[email protected]ffcdc9632014-03-27 17:25:23117
118GLSurfaceOSMesaHeadless::~GLSurfaceOSMesaHeadless() { Destroy(); }
119
[email protected]ad7bbbd62011-04-22 23:04:37120} // namespace gfx