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

Side by Side Diff: content/browser/renderer_host/compositing_iosurface_context_mac.mm

Issue 311263003: Delete non-CoreAnimation code in RWHVMac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@swappressure
Patch Set: Update driver bug Created 6 years, 6 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 5 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
6 6
7 #include <OpenGL/gl.h> 7 #include <OpenGL/gl.h>
8 #include <OpenGL/OpenGL.h> 8 #include <OpenGL/OpenGL.h>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h" 14 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h"
15 #include "content/browser/gpu/gpu_data_manager_impl.h" 15 #include "content/browser/gpu/gpu_data_manager_impl.h"
16 #include "ui/base/ui_base_switches.h" 16 #include "ui/base/ui_base_switches.h"
17 #include "ui/gl/gl_switches.h" 17 #include "ui/gl/gl_switches.h"
18 #include "ui/gl/gpu_switching_manager.h" 18 #include "ui/gl/gpu_switching_manager.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 CoreAnimationStatus GetCoreAnimationStatus() {
23 static CoreAnimationStatus status =
24 CommandLine::ForCurrentProcess()->HasSwitch(
25 switches::kDisableCoreAnimation) ?
26 CORE_ANIMATION_DISABLED : CORE_ANIMATION_ENABLED;
27 return status;
28 }
29
30 // static 22 // static
31 scoped_refptr<CompositingIOSurfaceContext> 23 scoped_refptr<CompositingIOSurfaceContext>
32 CompositingIOSurfaceContext::Get(int window_number) { 24 CompositingIOSurfaceContext::Get(int window_number) {
33 TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get"); 25 TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get");
34 26
35 // Return the context for this window_number, if it exists. 27 // Return the context for this window_number, if it exists.
36 WindowMap::iterator found = window_map()->find(window_number); 28 WindowMap::iterator found = window_map()->find(window_number);
37 if (found != window_map()->end()) { 29 if (found != window_map()->end()) {
38 DCHECK(!found->second->poisoned_); 30 DCHECK(!found->second->poisoned_);
39 return found->second; 31 return found->second;
40 } 32 }
41 33
42 static bool is_vsync_disabled = 34 static bool is_vsync_disabled =
43 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync); 35 CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
44 36
45 base::scoped_nsobject<NSOpenGLContext> nsgl_context;
46 base::ScopedTypeRef<CGLContextObj> cgl_context_strong; 37 base::ScopedTypeRef<CGLContextObj> cgl_context_strong;
47 CGLContextObj cgl_context = NULL; 38 CGLContextObj cgl_context = NULL;
48 if (GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED) { 39 CGLError error = kCGLNoError;
49 std::vector<NSOpenGLPixelFormatAttribute> attributes;
50 attributes.push_back(NSOpenGLPFADoubleBuffer);
51 // We don't need a depth buffer - try setting its size to 0...
52 attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0);
53 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
54 attributes.push_back(NSOpenGLPFAAllowOfflineRenderers);
55 attributes.push_back(0);
56 40
57 base::scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat( 41 // Create the pixel format object for the context.
58 [[NSOpenGLPixelFormat alloc] initWithAttributes:&attributes.front()]); 42 std::vector<CGLPixelFormatAttribute> attribs;
59 if (!glPixelFormat) { 43 attribs.push_back(kCGLPFADepthSize);
60 LOG(ERROR) << "NSOpenGLPixelFormat initWithAttributes failed"; 44 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
61 return NULL; 45 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
62 } 46 attribs.push_back(kCGLPFAAllowOfflineRenderers);
47 attribs.push_back(static_cast<CGLPixelFormatAttribute>(1));
48 }
49 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
50 GLint number_virtual_screens = 0;
51 base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
52 error = CGLChoosePixelFormat(&attribs.front(),
53 pixel_format.InitializeInto(),
54 &number_virtual_screens);
55 if (error != kCGLNoError) {
56 LOG(ERROR) << "Failed to create pixel format object.";
57 return NULL;
58 }
63 59
64 // Create all contexts in the same share group so that the textures don't 60 // Create all contexts in the same share group so that the textures don't
65 // need to be recreated when transitioning contexts. 61 // need to be recreated when transitioning contexts.
66 NSOpenGLContext* share_context = nil; 62 CGLContextObj share_context = NULL;
67 if (!window_map()->empty()) 63 if (!window_map()->empty())
68 share_context = window_map()->begin()->second->nsgl_context(); 64 share_context = window_map()->begin()->second->cgl_context();
69 nsgl_context.reset( 65 error = CGLCreateContext(
70 [[NSOpenGLContext alloc] initWithFormat:glPixelFormat 66 pixel_format, share_context, cgl_context_strong.InitializeInto());
71 shareContext:share_context]); 67 if (error != kCGLNoError) {
72 if (!nsgl_context) { 68 LOG(ERROR) << "Failed to create context object.";
73 LOG(ERROR) << "NSOpenGLContext initWithFormat failed"; 69 return NULL;
74 return NULL; 70 }
75 } 71 cgl_context = cgl_context_strong;
76 72
77 // Grab the CGL context that the NSGL context is using. Explicitly 73 // Note that VSync is ignored because CoreAnimation will automatically
78 // retain it, so that it is not double-freed by the scoped type. 74 // rate limit draws.
79 cgl_context = reinterpret_cast<CGLContextObj>(
80 [nsgl_context CGLContextObj]);
81 if (!cgl_context) {
82 LOG(ERROR) << "Failed to retrieve CGLContextObj from NSOpenGLContext";
83 return NULL;
84 }
85
86 // Force [nsgl_context flushBuffer] to wait for vsync.
87 GLint swapInterval = is_vsync_disabled ? 0 : 1;
88 [nsgl_context setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
89 } else {
90 CGLError error = kCGLNoError;
91
92 // Create the pixel format object for the context.
93 std::vector<CGLPixelFormatAttribute> attribs;
94 attribs.push_back(kCGLPFADepthSize);
95 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
96 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
97 attribs.push_back(kCGLPFAAllowOfflineRenderers);
98 attribs.push_back(static_cast<CGLPixelFormatAttribute>(1));
99 }
100 attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
101 GLint number_virtual_screens = 0;
102 base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
103 error = CGLChoosePixelFormat(&attribs.front(),
104 pixel_format.InitializeInto(),
105 &number_virtual_screens);
106 if (error != kCGLNoError) {
107 LOG(ERROR) << "Failed to create pixel format object.";
108 return NULL;
109 }
110
111 // Create all contexts in the same share group so that the textures don't
112 // need to be recreated when transitioning contexts.
113 CGLContextObj share_context = NULL;
114 if (!window_map()->empty())
115 share_context = window_map()->begin()->second->cgl_context();
116 error = CGLCreateContext(
117 pixel_format, share_context, cgl_context_strong.InitializeInto());
118 if (error != kCGLNoError) {
119 LOG(ERROR) << "Failed to create context object.";
120 return NULL;
121 }
122 cgl_context = cgl_context_strong;
123
124 // Note that VSync is ignored because CoreAnimation will automatically
125 // rate limit draws.
126 }
127 75
128 // Prepare the shader program cache. Precompile the shader programs 76 // Prepare the shader program cache. Precompile the shader programs
129 // needed to draw the IO Surface for non-offscreen contexts. 77 // needed to draw the IO Surface for non-offscreen contexts.
130 bool prepared = false; 78 bool prepared = false;
131 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache; 79 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache;
132 { 80 {
133 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context); 81 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context);
134 shader_program_cache.reset(new CompositingIOSurfaceShaderPrograms()); 82 shader_program_cache.reset(new CompositingIOSurfaceShaderPrograms());
135 if (window_number == kOffscreenContextWindowNumber) { 83 if (window_number == kOffscreenContextWindowNumber) {
136 prepared = true; 84 prepared = true;
137 } else { 85 } else {
138 prepared = ( 86 prepared = (
139 shader_program_cache->UseBlitProgram() && 87 shader_program_cache->UseBlitProgram() &&
140 shader_program_cache->UseSolidWhiteProgram()); 88 shader_program_cache->UseSolidWhiteProgram());
141 } 89 }
142 glUseProgram(0u); 90 glUseProgram(0u);
143 } 91 }
144 if (!prepared) { 92 if (!prepared) {
145 LOG(ERROR) << "IOSurface failed to compile/link required shader programs."; 93 LOG(ERROR) << "IOSurface failed to compile/link required shader programs.";
146 return NULL; 94 return NULL;
147 } 95 }
148 96
149 return new CompositingIOSurfaceContext( 97 return new CompositingIOSurfaceContext(
150 window_number, 98 window_number,
151 nsgl_context.release(),
152 cgl_context_strong, 99 cgl_context_strong,
153 cgl_context, 100 cgl_context,
154 is_vsync_disabled, 101 is_vsync_disabled,
155 shader_program_cache.Pass()); 102 shader_program_cache.Pass());
156 } 103 }
157 104
158 void CompositingIOSurfaceContext::PoisonContextAndSharegroup() { 105 void CompositingIOSurfaceContext::PoisonContextAndSharegroup() {
159 if (poisoned_) 106 if (poisoned_)
160 return; 107 return;
161 108
162 for (WindowMap::iterator it = window_map()->begin(); 109 for (WindowMap::iterator it = window_map()->begin();
163 it != window_map()->end(); 110 it != window_map()->end();
164 ++it) { 111 ++it) {
165 it->second->poisoned_ = true; 112 it->second->poisoned_ = true;
166 } 113 }
167 window_map()->clear(); 114 window_map()->clear();
168 } 115 }
169 116
170 CompositingIOSurfaceContext::CompositingIOSurfaceContext( 117 CompositingIOSurfaceContext::CompositingIOSurfaceContext(
171 int window_number, 118 int window_number,
172 NSOpenGLContext* nsgl_context,
173 base::ScopedTypeRef<CGLContextObj> cgl_context_strong, 119 base::ScopedTypeRef<CGLContextObj> cgl_context_strong,
174 CGLContextObj cgl_context, 120 CGLContextObj cgl_context,
175 bool is_vsync_disabled, 121 bool is_vsync_disabled,
176 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache) 122 scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache)
177 : window_number_(window_number), 123 : window_number_(window_number),
178 nsgl_context_(nsgl_context),
179 cgl_context_strong_(cgl_context_strong), 124 cgl_context_strong_(cgl_context_strong),
180 cgl_context_(cgl_context), 125 cgl_context_(cgl_context),
181 is_vsync_disabled_(is_vsync_disabled), 126 is_vsync_disabled_(is_vsync_disabled),
182 shader_program_cache_(shader_program_cache.Pass()), 127 shader_program_cache_(shader_program_cache.Pass()),
183 poisoned_(false) { 128 poisoned_(false) {
184 DCHECK(window_map()->find(window_number_) == window_map()->end()); 129 DCHECK(window_map()->find(window_number_) == window_map()->end());
185 window_map()->insert(std::make_pair(window_number_, this)); 130 window_map()->insert(std::make_pair(window_number_, this));
186 131
187 GpuDataManager::GetInstance()->AddObserver(this); 132 GpuDataManager::GetInstance()->AddObserver(this);
188 } 133 }
189 134
190 CompositingIOSurfaceContext::~CompositingIOSurfaceContext() { 135 CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
191 GpuDataManager::GetInstance()->RemoveObserver(this); 136 GpuDataManager::GetInstance()->RemoveObserver(this);
192 137
193 { 138 {
194 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context_); 139 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(cgl_context_);
195 shader_program_cache_->Reset(); 140 shader_program_cache_->Reset();
196 } 141 }
197 if (!poisoned_) { 142 if (!poisoned_) {
198 DCHECK(window_map()->find(window_number_) != window_map()->end()); 143 DCHECK(window_map()->find(window_number_) != window_map()->end());
199 DCHECK(window_map()->find(window_number_)->second == this); 144 DCHECK(window_map()->find(window_number_)->second == this);
200 window_map()->erase(window_number_); 145 window_map()->erase(window_number_);
201 } else { 146 } else {
202 WindowMap::const_iterator found = window_map()->find(window_number_); 147 WindowMap::const_iterator found = window_map()->find(window_number_);
203 if (found != window_map()->end()) 148 if (found != window_map()->end())
204 DCHECK(found->second != this); 149 DCHECK(found->second != this);
205 } 150 }
206 } 151 }
207 152
208 NSOpenGLContext* CompositingIOSurfaceContext::nsgl_context() const {
209 // This should not be called from any CoreAnimation paths.
210 CHECK(GetCoreAnimationStatus() == CORE_ANIMATION_DISABLED);
211 return nsgl_context_;
212 }
213
214 void CompositingIOSurfaceContext::OnGpuSwitching() { 153 void CompositingIOSurfaceContext::OnGpuSwitching() {
215 // Recreate all browser-side GL contexts whenever the GPU switches. If this 154 // Recreate all browser-side GL contexts whenever the GPU switches. If this
216 // is not done, performance will suffer. 155 // is not done, performance will suffer.
217 // http://crbug.com/361493 156 // http://crbug.com/361493
218 PoisonContextAndSharegroup(); 157 PoisonContextAndSharegroup();
219 } 158 }
220 159
221 // static 160 // static
222 CompositingIOSurfaceContext::WindowMap* 161 CompositingIOSurfaceContext::WindowMap*
223 CompositingIOSurfaceContext::window_map() { 162 CompositingIOSurfaceContext::window_map() {
224 return window_map_.Pointer(); 163 return window_map_.Pointer();
225 } 164 }
226 165
227 // static 166 // static
228 base::LazyInstance<CompositingIOSurfaceContext::WindowMap> 167 base::LazyInstance<CompositingIOSurfaceContext::WindowMap>
229 CompositingIOSurfaceContext::window_map_; 168 CompositingIOSurfaceContext::window_map_;
230 169
231 } // namespace content 170 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698