Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Side by Side Diff: ui/gl/gl_visual_picker_glx.cc

Issue 2347383002: X11: Use better visuals for OpenGL (Closed)
Patch Set: Fix various tests Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gl/gl_visual_picker_glx.h"
6
7 #include <algorithm>
8 #include <numeric>
9 #include <vector>
10
11 #include "base/memory/singleton.h"
12 #include "ui/gfx/x/x11_types.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_context.h"
15 #include "ui/gl/gl_surface_glx.h"
16
17 namespace gl {
18
19 namespace {
20
21 bool IsRgbaVisual(const XVisualInfo& visual) {
22 return visual.depth == 32 && visual.red_mask == 0xff0000 &&
23 visual.green_mask == 0x00ff00 && visual.blue_mask == 0x0000ff;
24 }
25
26 } // anonymous namespace
27
28 // static
29 GLVisualPickerGLX* GLVisualPickerGLX::GetInstance() {
30 return base::Singleton<GLVisualPickerGLX>::get();
31 }
32
33 XVisualInfo GLVisualPickerGLX::PickBestGlVisual(
34 const std::vector<XVisualInfo>& visuals,
35 bool want_alpha) const {
36 // Find the highest scoring visual and return it.
37 int highest_score = -1;
38 XVisualInfo best_visual{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
39 for (const XVisualInfo& const_visual_info : visuals) {
40 int supports_gl, double_buffer, stereo, alpha_size, depth_size,
41 stencil_size, num_multisample, visual_caveat;
42 // glXGetConfig unfortunately doesn't use const.
43 XVisualInfo* visual_info = const_cast<XVisualInfo*>(&const_visual_info);
44 if (glXGetConfig(display_, visual_info, GLX_USE_GL, &supports_gl) ||
45 !supports_gl ||
46 glXGetConfig(display_, visual_info, GLX_DOUBLEBUFFER, &double_buffer) ||
47 !double_buffer ||
48 glXGetConfig(display_, visual_info, GLX_STEREO, &stereo) || stereo) {
49 continue;
50 }
51 if (has_glx_visual_rating_) {
52 if (glXGetConfig(display_, visual_info, GLX_VISUAL_CAVEAT_EXT,
53 &visual_caveat) ||
54 visual_caveat != GLX_NONE_EXT) {
55 continue;
56 }
57 }
58
59 int score = 0;
60 if (!has_glx_multisample_ ||
61 (!glXGetConfig(display_, visual_info, GLX_SAMPLE_BUFFERS_ARB,
62 &num_multisample) &&
63 num_multisample == 0)) {
64 score++;
65 if (!glXGetConfig(display_, visual_info, GLX_DEPTH_SIZE, &depth_size) &&
66 depth_size == 0 &&
67 !glXGetConfig(display_, visual_info, GLX_STENCIL_SIZE,
68 &stencil_size) &&
69 stencil_size == 0) {
70 score++;
71 if (!glXGetConfig(display_, visual_info, GLX_ALPHA_SIZE, &alpha_size) &&
72 (alpha_size > 0) == want_alpha) {
73 score++;
74 }
75 }
76 }
77
78 if (score > highest_score) {
79 highest_score = score;
80 best_visual = const_visual_info;
81 }
82 }
83 return best_visual;
84 }
85
86 XVisualInfo GLVisualPickerGLX::PickBestSystemVisual(
87 const std::vector<XVisualInfo>& visuals) const {
88 Visual* default_visual = DefaultVisual(display_, DefaultScreen(display_));
89 auto it = std::find_if(visuals.begin(), visuals.end(),
90 [default_visual](const XVisualInfo& visual_info) {
91 return visual_info.visual == default_visual;
92 });
93 DCHECK(it != visuals.end());
94
95 const XVisualInfo& default_visual_info = *it;
96 std::vector<XVisualInfo> filtered_visuals;
97 std::copy_if(
98 visuals.begin(), visuals.end(), std::back_inserter(filtered_visuals),
99 [&default_visual_info](const XVisualInfo& visual_info) {
100 const XVisualInfo& v1 = visual_info;
101 const XVisualInfo& v2 = default_visual_info;
102 return v1.c_class == v2.c_class && v1.depth == v2.depth &&
103 v1.red_mask == v2.red_mask && v1.green_mask == v2.green_mask &&
104 v1.blue_mask == v2.blue_mask &&
105 v1.colormap_size == v2.colormap_size &&
106 v1.bits_per_rgb == v2.bits_per_rgb;
107 });
108 return PickBestGlVisual(filtered_visuals, IsRgbaVisual(default_visual_info));
piman 2016/09/22 21:24:55 For offscreen and opaque windows, the best visual
Tom (Use chromium acct) 2016/09/23 20:00:38 On my system there's a bunch of visuals that have
piman 2016/09/26 21:13:29 It's hard to know without testing, in particular w
109 }
110
111 XVisualInfo GLVisualPickerGLX::PickBestRgbaVisual(
112 const std::vector<XVisualInfo>& visuals) const {
113 // Filter the visuals by the best class.
114 auto score = [](int c_class) {
115 // A higher score is more preferable.
116 switch (c_class) {
117 case StaticGray:
118 return 5;
piman 2016/09/22 21:24:55 Why is StaticGray first? I don't think we want an
Tom (Use chromium acct) 2016/09/23 20:00:38 Done.
119 case TrueColor:
120 return 4;
121 case PseudoColor:
122 return 3;
123 case StaticColor:
124 return 2;
125 case GrayScale:
126 return 1;
127 case DirectColor:
128 return 0;
129 default:
130 return -1;
131 }
132 };
133 int best_class_score =
134 std::accumulate(visuals.begin(), visuals.end(), -1,
135 [&score](int acc, const XVisualInfo& visual_info) {
136 return std::max(acc, score(visual_info.c_class));
137 });
138 std::vector<XVisualInfo> filtered_visuals;
139 std::copy_if(visuals.begin(), visuals.end(),
140 std::back_inserter(filtered_visuals),
141 [best_class_score, &score](const XVisualInfo& visual_info) {
142 return score(visual_info.c_class) == best_class_score;
143 });
144
145 // Now filter out only 8888 RGBA visuals.
146 std::remove_if(filtered_visuals.begin(), filtered_visuals.end(),
piman 2016/09/22 21:24:55 Note: remove_if doesn't remove anything, it just m
Tom (Use chromium acct) 2016/09/23 20:00:38 Done. Nice catch, I think the reason it was retur
piman 2016/09/26 21:13:29 But you don't want to check inside the copy_if? It
147 [](const XVisualInfo& visual_info) {
148 return !IsRgbaVisual(visual_info);
149 });
150
151 return PickBestGlVisual(filtered_visuals, true);
152 }
153
154 GLVisualPickerGLX::GLVisualPickerGLX() : display_(gfx::GetXDisplay()) {
155 has_glx_visual_rating_ =
156 GLSurfaceGLX::HasGLXExtension("GLX_EXT_visual_rating");
157 has_glx_multisample_ = GLSurfaceGLX::HasGLXExtension("GLX_EXT_multisample");
158
159 XVisualInfo visual_template;
160 visual_template.screen = DefaultScreen(display_);
161
162 // Get all of the visuals for the default screen.
163 int n_visuals;
164 gfx::XScopedPtr<XVisualInfo[]> x_visuals(
165 XGetVisualInfo(display_, VisualScreenMask, &visual_template, &n_visuals));
166 std::vector<XVisualInfo> visuals;
167 for (int i = 0; i < n_visuals; i++)
168 visuals.push_back(x_visuals[i]);
169
170 system_visual_ = PickBestSystemVisual(visuals);
171 rgba_visual_ = PickBestRgbaVisual(visuals);
172 }
173
174 GLVisualPickerGLX::~GLVisualPickerGLX() {}
175
176 } // namespace gl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698