Commit 380677c2 authored by Zhenyao Mo's avatar Zhenyao Mo Committed by Commit Bot

Make sure we create/use/delete buffer on the same context.

This is for GLImageMemory's optimization path.

BUG=1087047
TEST=manual
R=kbr@chromium.org,khushalsagar@chromium.org

Change-Id: I82d3ceeac36644f95e3a52b2a943c4ecaeb651d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2226926Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774927}
parent 03e10196
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/atomic_flag.h" #include "base/synchronization/atomic_flag.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "ui/gfx/extension_set.h" #include "ui/gfx/extension_set.h"
...@@ -90,7 +91,8 @@ struct GL_EXPORT GLContextAttribs { ...@@ -90,7 +91,8 @@ struct GL_EXPORT GLContextAttribs {
}; };
// Encapsulates an OpenGL context, hiding platform specific management. // Encapsulates an OpenGL context, hiding platform specific management.
class GL_EXPORT GLContext : public base::RefCounted<GLContext> { class GL_EXPORT GLContext : public base::RefCounted<GLContext>,
public base::SupportsWeakPtr<GLContext> {
public: public:
explicit GLContext(GLShareGroup* share_group); explicit GLContext(GLShareGroup* share_group);
......
...@@ -21,8 +21,10 @@ ...@@ -21,8 +21,10 @@
#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h" #include "ui/gl/gl_context.h"
#include "ui/gl/gl_enums.h" #include "ui/gl/gl_enums.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_version_info.h" #include "ui/gl/gl_version_info.h"
#include "ui/gl/scoped_binders.h" #include "ui/gl/scoped_binders.h"
#include "ui/gl/scoped_make_current.h"
using gfx::BufferFormat; using gfx::BufferFormat;
...@@ -227,8 +229,11 @@ GLImageMemory::GLImageMemory(const gfx::Size& size) ...@@ -227,8 +229,11 @@ GLImageMemory::GLImageMemory(const gfx::Size& size)
stride_(0) {} stride_(0) {}
GLImageMemory::~GLImageMemory() { GLImageMemory::~GLImageMemory() {
if (buffer_) if (buffer_ && original_context_ && original_surface_) {
ui::ScopedMakeCurrent make_current(original_context_.get(),
original_surface_.get());
glDeleteBuffersARB(1, &buffer_); glDeleteBuffersARB(1, &buffer_);
}
} }
// static // static
...@@ -262,6 +267,7 @@ bool GLImageMemory::Initialize(const unsigned char* memory, ...@@ -262,6 +267,7 @@ bool GLImageMemory::Initialize(const unsigned char* memory,
tex_image_from_pbo_is_slow = true; tex_image_from_pbo_is_slow = true;
#endif // OS_WIN #endif // OS_WIN
GLContext* context = GLContext::GetCurrent(); GLContext* context = GLContext::GetCurrent();
DCHECK(context);
if (!tex_image_from_pbo_is_slow && SupportsPBO(context) && if (!tex_image_from_pbo_is_slow && SupportsPBO(context) &&
(SupportsMapBuffer(context) || SupportsMapBufferRange(context))) { (SupportsMapBuffer(context) || SupportsMapBufferRange(context))) {
constexpr size_t kTaskBytes = 1024 * 1024; constexpr size_t kTaskBytes = 1024 * 1024;
...@@ -273,6 +279,10 @@ bool GLImageMemory::Initialize(const unsigned char* memory, ...@@ -273,6 +279,10 @@ bool GLImageMemory::Initialize(const unsigned char* memory,
ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_); ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_);
glBufferData(GL_PIXEL_UNPACK_BUFFER, buffer_bytes_, nullptr, glBufferData(GL_PIXEL_UNPACK_BUFFER, buffer_bytes_, nullptr,
GL_DYNAMIC_DRAW); GL_DYNAMIC_DRAW);
original_context_ = context->AsWeakPtr();
GLSurface* surface = GLSurface::GetCurrent();
DCHECK(surface);
original_surface_ = surface->AsWeakPtr();
} }
} }
...@@ -332,7 +342,9 @@ bool GLImageMemory::CopyTexImage(unsigned target) { ...@@ -332,7 +342,9 @@ bool GLImageMemory::CopyTexImage(unsigned target) {
GLint data_row_length = DataRowLength(stride_, format_); GLint data_row_length = DataRowLength(stride_, format_);
base::Optional<std::vector<uint8_t>> gles2_data; base::Optional<std::vector<uint8_t>> gles2_data;
if (GLContext::GetCurrent()->GetVersionInfo()->is_es) { GLContext* context = GLContext::GetCurrent();
DCHECK(context);
if (context->GetVersionInfo()->is_es) {
gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format, gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format,
&data_type, &data_row_length); &data_type, &data_row_length);
} }
...@@ -350,17 +362,18 @@ bool GLImageMemory::CopyTexImage(unsigned target) { ...@@ -350,17 +362,18 @@ bool GLImageMemory::CopyTexImage(unsigned target) {
size = buffer_bytes_; size = buffer_bytes_;
} }
if (buffer_) { bool uploaded = false;
if (buffer_ && original_context_.get() == context) {
glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(), glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(),
0, data_format, data_type, nullptr); 0, data_format, data_type, nullptr);
ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_); ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_);
void* dst = nullptr; void* dst = nullptr;
if (SupportsMapBuffer(GLContext::GetCurrent())) { if (SupportsMapBuffer(context)) {
dst = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); dst = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
} else { } else {
DCHECK(SupportsMapBufferRange(GLContext::GetCurrent())); DCHECK(SupportsMapBufferRange(context));
dst = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT); dst = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT);
} }
...@@ -381,13 +394,14 @@ bool GLImageMemory::CopyTexImage(unsigned target) { ...@@ -381,13 +394,14 @@ bool GLImageMemory::CopyTexImage(unsigned target) {
glTexSubImage2D(target, 0, 0, 0, size_.width(), size_.height(), glTexSubImage2D(target, 0, 0, 0, size_.width(), size_.height(),
data_format, data_type, 0); data_format, data_type, 0);
uploaded = true;
} else { } else {
glDeleteBuffersARB(1, &buffer_); glDeleteBuffersARB(1, &buffer_);
buffer_ = 0; buffer_ = 0;
} }
} }
if (!buffer_) { if (!uploaded) {
glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(), glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(),
0, data_format, data_type, src); 0, data_format, data_type, src);
} }
......
...@@ -10,11 +10,14 @@ ...@@ -10,11 +10,14 @@
#include <stddef.h> #include <stddef.h>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_math.h" #include "base/numerics/safe_math.h"
#include "ui/gfx/buffer_types.h" #include "ui/gfx/buffer_types.h"
#include "ui/gl/gl_export.h" #include "ui/gl/gl_export.h"
namespace gl { namespace gl {
class GLContext;
class GLSurface;
class GL_EXPORT GLImageMemory : public GLImage { class GL_EXPORT GLImageMemory : public GLImage {
public: public:
...@@ -65,6 +68,9 @@ class GL_EXPORT GLImageMemory : public GLImage { ...@@ -65,6 +68,9 @@ class GL_EXPORT GLImageMemory : public GLImage {
size_t stride_; size_t stride_;
unsigned buffer_ = 0; unsigned buffer_ = 0;
// The context/surface from which the |buffer_| is created.
base::WeakPtr<GLContext> original_context_;
base::WeakPtr<GLSurface> original_surface_;
size_t buffer_bytes_ = 0; size_t buffer_bytes_ = 0;
int memcpy_tasks_ = 0; int memcpy_tasks_ = 0;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/rect_f.h"
...@@ -44,7 +45,8 @@ class EGLTimestampClient; ...@@ -44,7 +45,8 @@ class EGLTimestampClient;
// Encapsulates a surface that can be rendered to with GL, hiding platform // Encapsulates a surface that can be rendered to with GL, hiding platform
// specific management. // specific management.
class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { class GL_EXPORT GLSurface : public base::RefCounted<GLSurface>,
public base::SupportsWeakPtr<GLSurface> {
public: public:
GLSurface(); GLSurface();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment