Remove GLContextCGL and cleanup relevant code
GLContextCGL is not used anymore and wasn't referenced. Change-Id: Ie767727120f5274a3191962b6b7dbef32a5529ae Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4301154 Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org> Reviewed-by: ccameron chromium <ccameron@chromium.org> Cr-Commit-Position: refs/heads/main@{#1112355}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
36b3893df1
commit
46c57f9588
@ -15,7 +15,6 @@
|
||||
#include "ui/gfx/presentation_feedback.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_surface.h"
|
||||
#include "ui/gl/gpu_switching_observer.h"
|
||||
#include "ui/gl/presenter.h"
|
||||
|
||||
@class CAContext;
|
||||
@ -32,8 +31,7 @@ class GLFence;
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter,
|
||||
public ui::GpuSwitchingObserver {
|
||||
class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter {
|
||||
public:
|
||||
using VSyncCallback =
|
||||
base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>;
|
||||
@ -53,16 +51,12 @@ class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter,
|
||||
|
||||
// TODO(vasilyt): Remove this.
|
||||
bool SupportsCommitOverlayPlanes() override;
|
||||
bool OnMakeCurrent(gl::GLContext* context) override;
|
||||
bool ScheduleOverlayPlane(
|
||||
gl::OverlayImage image,
|
||||
std::unique_ptr<gfx::GpuFence> gpu_fence,
|
||||
const gfx::OverlayPlaneData& overlay_plane_data) override;
|
||||
bool ScheduleCALayer(const ui::CARendererLayerParams& params) override;
|
||||
|
||||
// ui::GpuSwitchingObserver implementation.
|
||||
void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
|
||||
|
||||
void SetCALayerErrorCode(gfx::CALayerResult ca_layer_error_code) override;
|
||||
|
||||
// GLSurface override
|
||||
@ -99,9 +93,6 @@ class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter,
|
||||
const VSyncCallback vsync_callback_;
|
||||
bool gpu_vsync_enabled_ = false;
|
||||
|
||||
// The renderer ID that all contexts made current to this surface should be
|
||||
// targeting.
|
||||
GLint gl_renderer_id_;
|
||||
base::WeakPtrFactory<ImageTransportSurfaceOverlayMacEGL> weak_ptr_factory_;
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "ui/gfx/video_types.h"
|
||||
#include "ui/gl/ca_renderer_layer_params.h"
|
||||
#include "ui/gl/gl_features.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "ui/accelerated_widget_mac/io_surface_context.h"
|
||||
@ -63,9 +62,7 @@ ImageTransportSurfaceOverlayMacEGL::ImageTransportSurfaceOverlayMacEGL(
|
||||
#endif
|
||||
scale_factor_(1),
|
||||
vsync_callback_(delegate->GetGpuVSyncCallback()),
|
||||
gl_renderer_id_(0),
|
||||
weak_ptr_factory_(this) {
|
||||
ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
|
||||
|
||||
static bool av_disabled_at_command_line =
|
||||
!base::FeatureList::IsEnabled(kAVFoundationOverlays);
|
||||
@ -95,7 +92,6 @@ ImageTransportSurfaceOverlayMacEGL::ImageTransportSurfaceOverlayMacEGL(
|
||||
}
|
||||
|
||||
ImageTransportSurfaceOverlayMacEGL::~ImageTransportSurfaceOverlayMacEGL() {
|
||||
ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
|
||||
ca_layer_tree_coordinator_.reset();
|
||||
}
|
||||
|
||||
@ -216,14 +212,6 @@ bool ImageTransportSurfaceOverlayMacEGL::SupportsCommitOverlayPlanes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImageTransportSurfaceOverlayMacEGL::OnMakeCurrent(gl::GLContext* context) {
|
||||
// Ensure that the context is on the appropriate GL renderer. The GL renderer
|
||||
// will generally only change when the GPU changes.
|
||||
if (gl_renderer_id_ && context)
|
||||
context->share_group()->SetRendererID(gl_renderer_id_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImageTransportSurfaceOverlayMacEGL::ScheduleOverlayPlane(
|
||||
gl::OverlayImage image,
|
||||
std::unique_ptr<gfx::GpuFence> gpu_fence,
|
||||
@ -275,31 +263,6 @@ bool ImageTransportSurfaceOverlayMacEGL::Resize(
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImageTransportSurfaceOverlayMacEGL::OnGpuSwitched(
|
||||
gl::GpuPreference active_gpu_heuristic) {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// Create a new context, and use the GL renderer ID that the new context gets.
|
||||
scoped_refptr<ui::IOSurfaceContext> context_on_new_gpu =
|
||||
ui::IOSurfaceContext::Get(ui::IOSurfaceContext::kCALayerContext);
|
||||
if (!context_on_new_gpu)
|
||||
return;
|
||||
GLint context_renderer_id = -1;
|
||||
if (CGLGetParameter(context_on_new_gpu->cgl_context(),
|
||||
kCGLCPCurrentRendererID,
|
||||
&context_renderer_id) != kCGLNoError) {
|
||||
LOG(ERROR) << "Failed to create test context after GPU switch";
|
||||
return;
|
||||
}
|
||||
gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask;
|
||||
|
||||
// Delay releasing the reference to the new GL context. The reason for this
|
||||
// is to avoid creating-then-destroying the context for every image transport
|
||||
// surface that is observing the GPU switch.
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()->ReleaseSoon(
|
||||
FROM_HERE, std::move(context_on_new_gpu));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImageTransportSurfaceOverlayMacEGL::SetCALayerErrorCode(
|
||||
gfx::CALayerResult ca_layer_error_code) {
|
||||
ca_layer_error_code_ = ca_layer_error_code;
|
||||
|
@ -369,8 +369,6 @@ component("gl") {
|
||||
"dual_gpu_state_mac.h",
|
||||
"egl_surface_io_surface.cc",
|
||||
"egl_surface_io_surface.h",
|
||||
"gl_context_cgl.cc",
|
||||
"gl_context_cgl.h",
|
||||
"gl_display_egl.mm",
|
||||
"gl_fence_apple.cc",
|
||||
"gl_fence_apple.h",
|
||||
|
@ -1,283 +0,0 @@
|
||||
// Copyright 2012 The Chromium Authors
|
||||
// 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_cgl.h"
|
||||
|
||||
#include <OpenGL/CGLRenderers.h>
|
||||
#include <OpenGL/CGLTypes.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/location.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "ui/gl/dual_gpu_state_mac.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_gl_api_implementation.h"
|
||||
#include "ui/gl/gl_implementation.h"
|
||||
#include "ui/gl/gl_surface.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/gl/scoped_cgl.h"
|
||||
|
||||
namespace gl {
|
||||
|
||||
namespace {
|
||||
|
||||
bool g_support_renderer_switching;
|
||||
|
||||
} // namespace
|
||||
|
||||
static CGLPixelFormatObj GetPixelFormat() {
|
||||
static CGLPixelFormatObj format;
|
||||
if (format)
|
||||
return format;
|
||||
std::vector<CGLPixelFormatAttribute> attribs;
|
||||
// If the system supports dual gpus then allow offline renderers for every
|
||||
// context, so that they can all be in the same share group.
|
||||
if (GLContext::SwitchableGPUsSupported()) {
|
||||
attribs.push_back(kCGLPFAAllowOfflineRenderers);
|
||||
g_support_renderer_switching = true;
|
||||
}
|
||||
if (GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) {
|
||||
attribs.push_back(kCGLPFAOpenGLProfile);
|
||||
attribs.push_back((CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core);
|
||||
}
|
||||
|
||||
attribs.push_back((CGLPixelFormatAttribute) 0);
|
||||
|
||||
GLint num_virtual_screens;
|
||||
if (CGLChoosePixelFormat(&attribs.front(),
|
||||
&format,
|
||||
&num_virtual_screens) != kCGLNoError) {
|
||||
LOG(ERROR) << "Error choosing pixel format.";
|
||||
return nullptr;
|
||||
}
|
||||
if (!format) {
|
||||
LOG(ERROR) << "format == 0.";
|
||||
return nullptr;
|
||||
}
|
||||
DCHECK_NE(num_virtual_screens, 0);
|
||||
return format;
|
||||
}
|
||||
|
||||
GLContextCGL::GLContextCGL(GLShareGroup* share_group)
|
||||
: GLContextReal(share_group) {}
|
||||
|
||||
bool GLContextCGL::Initialize(GLSurface* compatible_surface,
|
||||
const GLContextAttribs& attribs) {
|
||||
DCHECK(compatible_surface);
|
||||
DCHECK(share_group());
|
||||
|
||||
// webgl_compatibility_context and disabling bind_generates_resource are not
|
||||
// supported.
|
||||
DCHECK(!attribs.webgl_compatibility_context &&
|
||||
attribs.bind_generates_resource);
|
||||
|
||||
GpuPreference gpu_preference =
|
||||
GLSurface::AdjustGpuPreference(attribs.gpu_preference);
|
||||
|
||||
CGLPixelFormatObj format = GetPixelFormat();
|
||||
if (!format)
|
||||
return false;
|
||||
|
||||
// If using the discrete gpu, create a pixel format requiring it before we
|
||||
// create the context. If switchable GPUs are unsupported, we should bias
|
||||
// toward the discrete gpu.
|
||||
if (!GLContext::SwitchableGPUsSupported() ||
|
||||
gpu_preference == GpuPreference::kHighPerformance) {
|
||||
DualGPUStateMac::GetInstance()->RegisterHighPerformanceContext(this);
|
||||
is_high_performance_context_ = true;
|
||||
// The renderer might be switched after this, so ignore the saved ID.
|
||||
share_group()->SetRendererID(-1);
|
||||
}
|
||||
|
||||
CGLError res = CGLCreateContext(
|
||||
format, static_cast<CGLContextObj>(share_group()->GetHandle()),
|
||||
reinterpret_cast<CGLContextObj*>(&context_));
|
||||
if (res != kCGLNoError) {
|
||||
LOG(ERROR) << "Error creating context.";
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
gpu_preference_ = gpu_preference;
|
||||
// Contexts that prefer low power gpu are known to use only the subset of GL
|
||||
// that can be safely migrated between the iGPU and the dGPU. Mark those
|
||||
// contexts as safe to forcibly transition between the GPUs by default.
|
||||
// http://crbug.com/180876, http://crbug.com/227228
|
||||
safe_to_force_gpu_switch_ = gpu_preference == GpuPreference::kLowPower;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLContextCGL::Destroy() {
|
||||
if (HasBackpressureFences()) {
|
||||
// If this context is not current, bind this context's API so that the YUV
|
||||
// converter and GLFences can safely destruct
|
||||
GLContext* current_context = GetRealCurrent();
|
||||
if (current_context != this) {
|
||||
SetCurrentGL(GetCurrentGL());
|
||||
}
|
||||
|
||||
ScopedCGLSetCurrentContext scoped_set_current(
|
||||
static_cast<CGLContextObj>(context_));
|
||||
DestroyBackpressureFences();
|
||||
|
||||
// Rebind the current context's API if needed.
|
||||
if (current_context && current_context != this) {
|
||||
SetCurrentGL(current_context->GetCurrentGL());
|
||||
}
|
||||
}
|
||||
|
||||
if (is_high_performance_context_) {
|
||||
DualGPUStateMac::GetInstance()->RemoveHighPerformanceContext(this);
|
||||
}
|
||||
if (context_) {
|
||||
CGLDestroyContext(static_cast<CGLContextObj>(context_));
|
||||
context_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLContextCGL::ForceGpuSwitchIfNeeded() {
|
||||
DCHECK(context_);
|
||||
|
||||
// The call to CGLSetVirtualScreen can hang on some AMD drivers
|
||||
// http://crbug.com/227228
|
||||
if (safe_to_force_gpu_switch_) {
|
||||
int renderer_id = share_group()->GetRendererID();
|
||||
int screen;
|
||||
CGLGetVirtualScreen(static_cast<CGLContextObj>(context_), &screen);
|
||||
|
||||
if (g_support_renderer_switching && !is_high_performance_context_ &&
|
||||
renderer_id != -1 &&
|
||||
(screen != screen_ || renderer_id != renderer_id_)) {
|
||||
// Attempt to find a virtual screen that's using the requested renderer,
|
||||
// and switch the context to use that screen. Don't attempt to switch if
|
||||
// the context requires the discrete GPU.
|
||||
CGLPixelFormatObj format = GetPixelFormat();
|
||||
int virtual_screen_count;
|
||||
if (CGLDescribePixelFormat(format, 0, kCGLPFAVirtualScreenCount,
|
||||
&virtual_screen_count) != kCGLNoError)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < virtual_screen_count; ++i) {
|
||||
int screen_renderer_id;
|
||||
if (CGLDescribePixelFormat(format, i, kCGLPFARendererID,
|
||||
&screen_renderer_id) != kCGLNoError)
|
||||
return false;
|
||||
|
||||
screen_renderer_id &= kCGLRendererIDMatchingMask;
|
||||
if (screen_renderer_id == renderer_id) {
|
||||
CGLSetVirtualScreen(static_cast<CGLContextObj>(context_), i);
|
||||
screen_ = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
renderer_id_ = renderer_id;
|
||||
has_switched_gpus_ = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLContextCGL::MakeCurrentImpl(GLSurface* surface) {
|
||||
DCHECK(context_);
|
||||
|
||||
if (!ForceGpuSwitchIfNeeded())
|
||||
return false;
|
||||
|
||||
if (IsCurrent(surface))
|
||||
return true;
|
||||
|
||||
// It's likely we're going to switch OpenGL contexts at this point.
|
||||
// Before doing so, if there is a current context, flush it. There
|
||||
// are many implicit assumptions of flush ordering between contexts
|
||||
// at higher levels, and if a flush isn't performed, OpenGL commands
|
||||
// may be issued in unexpected orders, causing flickering and other
|
||||
// artifacts.
|
||||
if (CGLGetCurrentContext() != nullptr) {
|
||||
glFlush();
|
||||
}
|
||||
|
||||
ScopedReleaseCurrent release_current;
|
||||
TRACE_EVENT0("gpu", "GLContextCGL::MakeCurrent");
|
||||
|
||||
if (CGLSetCurrentContext(
|
||||
static_cast<CGLContextObj>(context_)) != kCGLNoError) {
|
||||
LOG(ERROR) << "Unable to make gl context current.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set this as soon as the context is current, since we might call into GL.
|
||||
BindGLApi();
|
||||
|
||||
SetCurrent(surface);
|
||||
InitializeDynamicBindings();
|
||||
|
||||
if (!surface->OnMakeCurrent(this)) {
|
||||
LOG(ERROR) << "Unable to make gl context current.";
|
||||
return false;
|
||||
}
|
||||
|
||||
release_current.Cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLContextCGL::SetVisibility(bool visibility) {
|
||||
if (!is_high_performance_context_ || !g_support_renderer_switching)
|
||||
return;
|
||||
if (visibility)
|
||||
DualGPUStateMac::GetInstance()->RegisterHighPerformanceContext(this);
|
||||
else
|
||||
DualGPUStateMac::GetInstance()->RemoveHighPerformanceContext(this);
|
||||
}
|
||||
|
||||
void GLContextCGL::ReleaseCurrent(GLSurface* surface) {
|
||||
if (!IsCurrent(surface))
|
||||
return;
|
||||
|
||||
// Before releasing the current context, flush it. This ensures that
|
||||
// all commands issued by higher levels will be seen by the OpenGL
|
||||
// implementation, which is assumed throughout the code. See comment
|
||||
// in MakeCurrent, above.
|
||||
glFlush();
|
||||
|
||||
SetCurrent(nullptr);
|
||||
CGLSetCurrentContext(nullptr);
|
||||
}
|
||||
|
||||
bool GLContextCGL::IsCurrent(GLSurface* surface) {
|
||||
bool native_context_is_current = CGLGetCurrentContext() == context_;
|
||||
|
||||
// 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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* GLContextCGL::GetHandle() {
|
||||
return context_;
|
||||
}
|
||||
|
||||
void GLContextCGL::SetSafeToForceGpuSwitch() {
|
||||
safe_to_force_gpu_switch_ = true;
|
||||
}
|
||||
|
||||
GLContextCGL::~GLContextCGL() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
GpuPreference GLContextCGL::GetGpuPreference() {
|
||||
return gpu_preference_;
|
||||
}
|
||||
|
||||
} // namespace gl
|
@ -1,58 +0,0 @@
|
||||
// Copyright 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_GL_GL_CONTEXT_CGL_H_
|
||||
#define UI_GL_GL_CONTEXT_CGL_H_
|
||||
|
||||
#include <OpenGL/CGLTypes.h>
|
||||
|
||||
#include "ui/gfx/color_space.h"
|
||||
#include "ui/gl/gl_context.h"
|
||||
#include "ui/gl/gl_export.h"
|
||||
|
||||
namespace gl {
|
||||
|
||||
class GLSurface;
|
||||
|
||||
// Encapsulates a CGL OpenGL context.
|
||||
class GL_EXPORT GLContextCGL final : public GLContextReal {
|
||||
public:
|
||||
explicit GLContextCGL(GLShareGroup* share_group);
|
||||
|
||||
GLContextCGL(const GLContextCGL&) = delete;
|
||||
GLContextCGL& operator=(const GLContextCGL&) = delete;
|
||||
|
||||
// Implement GLContext.
|
||||
bool Initialize(GLSurface* compatible_surface,
|
||||
const GLContextAttribs& attribs) override;
|
||||
bool MakeCurrentImpl(GLSurface* surface) override;
|
||||
void ReleaseCurrent(GLSurface* surface) override;
|
||||
bool IsCurrent(GLSurface* surface) override;
|
||||
void* GetHandle() override;
|
||||
void SetSafeToForceGpuSwitch() override;
|
||||
bool ForceGpuSwitchIfNeeded() override;
|
||||
void SetVisibility(bool visibility) override;
|
||||
|
||||
protected:
|
||||
~GLContextCGL() override;
|
||||
|
||||
private:
|
||||
void Destroy();
|
||||
GpuPreference GetGpuPreference();
|
||||
|
||||
void* context_ = nullptr;
|
||||
GpuPreference gpu_preference_ = GpuPreference::kLowPower;
|
||||
|
||||
int screen_ = -1;
|
||||
int renderer_id_ = -1;
|
||||
bool safe_to_force_gpu_switch_ = true;
|
||||
bool is_high_performance_context_ = false;
|
||||
|
||||
// Debugging for https://crbug.com/863817
|
||||
bool has_switched_gpus_ = false;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
#endif // UI_GL_GL_CONTEXT_CGL_H_
|
@ -11,12 +11,7 @@
|
||||
|
||||
namespace gl {
|
||||
|
||||
GLShareGroup::GLShareGroup()
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
: renderer_id_(-1)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
GLShareGroup::GLShareGroup() = default;
|
||||
|
||||
void GLShareGroup::AddContext(GLContext* context) {
|
||||
contexts_.insert(context);
|
||||
@ -50,16 +45,6 @@ void GLShareGroup::SetSharedContext(GLContext* context) {
|
||||
shared_context_ = context;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
void GLShareGroup::SetRendererID(int renderer_id) {
|
||||
renderer_id_ = renderer_id;
|
||||
}
|
||||
|
||||
int GLShareGroup::GetRendererID() {
|
||||
return renderer_id_;
|
||||
}
|
||||
#endif
|
||||
|
||||
GLShareGroup::~GLShareGroup() {
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,6 @@ class GL_EXPORT GLShareGroup : public base::RefCounted<GLShareGroup> {
|
||||
void SetSharedContext(GLContext* context);
|
||||
GLContext* shared_context() { return shared_context_; }
|
||||
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
// Sets and returns the ID of the renderer that all contexts in this share
|
||||
// group should be on.
|
||||
void SetRendererID(int renderer_id);
|
||||
int GetRendererID();
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<GLShareGroup>;
|
||||
|
||||
@ -59,10 +52,6 @@ class GL_EXPORT GLShareGroup : public base::RefCounted<GLShareGroup> {
|
||||
ContextSet contexts_;
|
||||
|
||||
raw_ptr<GLContext> shared_context_ = nullptr;
|
||||
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
int renderer_id_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "ui/gl/buildflags.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_context_cgl.h"
|
||||
#include "ui/gl/gl_context_stub.h"
|
||||
#include "ui/gl/gl_implementation.h"
|
||||
#include "ui/gl/gl_share_group.h"
|
||||
|
Reference in New Issue
Block a user