Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / compositing_iosurface_context_mac.mm
blob5f0979293b3ce92007d012a36dd041f33e37b4be
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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
7 #include <OpenGL/gl.h>
8 #include <OpenGL/OpenGL.h>
9 #include <vector>
11 #include "base/command_line.h"
12 #include "base/debug/trace_event.h"
13 #include "base/logging.h"
14 #include "content/browser/gpu/gpu_data_manager_impl.h"
15 #include "ui/base/ui_base_switches.h"
16 #include "ui/gl/gl_switches.h"
17 #include "ui/gl/gpu_switching_manager.h"
19 namespace content {
21 // static
22 scoped_refptr<CompositingIOSurfaceContext>
23 CompositingIOSurfaceContext::Get(int window_number) {
24   TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get");
26   // Return the context for this window_number, if it exists.
27   WindowMap::iterator found = window_map()->find(window_number);
28   if (found != window_map()->end()) {
29     DCHECK(!found->second->poisoned_);
30     return found->second;
31   }
33   base::ScopedTypeRef<CGLContextObj> cgl_context_strong;
34   CGLContextObj cgl_context = NULL;
35   CGLError error = kCGLNoError;
37   // Create the pixel format object for the context.
38   std::vector<CGLPixelFormatAttribute> attribs;
39   attribs.push_back(kCGLPFADepthSize);
40   attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
41   if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
42     attribs.push_back(kCGLPFAAllowOfflineRenderers);
43     attribs.push_back(static_cast<CGLPixelFormatAttribute>(1));
44   }
45   attribs.push_back(static_cast<CGLPixelFormatAttribute>(0));
46   GLint number_virtual_screens = 0;
47   base::ScopedTypeRef<CGLPixelFormatObj> pixel_format;
48   error = CGLChoosePixelFormat(&attribs.front(),
49                                pixel_format.InitializeInto(),
50                                &number_virtual_screens);
51   if (error != kCGLNoError) {
52     LOG(ERROR) << "Failed to create pixel format object.";
53     return NULL;
54   }
56   // Create all contexts in the same share group so that the textures don't
57   // need to be recreated when transitioning contexts.
58   CGLContextObj share_context = NULL;
59   if (!window_map()->empty())
60     share_context = window_map()->begin()->second->cgl_context();
61   error = CGLCreateContext(
62       pixel_format, share_context, cgl_context_strong.InitializeInto());
63   if (error != kCGLNoError) {
64     LOG(ERROR) << "Failed to create context object.";
65     return NULL;
66   }
67   cgl_context = cgl_context_strong;
69   // Note that VSync is ignored because CoreAnimation will automatically
70   // rate limit draws.
72   return new CompositingIOSurfaceContext(
73       window_number,
74       cgl_context_strong,
75       cgl_context);
78 void CompositingIOSurfaceContext::PoisonContextAndSharegroup() {
79   if (poisoned_)
80     return;
82   for (WindowMap::iterator it = window_map()->begin();
83        it != window_map()->end();
84        ++it) {
85     it->second->poisoned_ = true;
86   }
87   window_map()->clear();
90 CompositingIOSurfaceContext::CompositingIOSurfaceContext(
91     int window_number,
92     base::ScopedTypeRef<CGLContextObj> cgl_context_strong,
93     CGLContextObj cgl_context)
94     : window_number_(window_number),
95       cgl_context_strong_(cgl_context_strong),
96       cgl_context_(cgl_context),
97       poisoned_(false) {
98   DCHECK(window_map()->find(window_number_) == window_map()->end());
99   window_map()->insert(std::make_pair(window_number_, this));
101   GpuDataManager::GetInstance()->AddObserver(this);
104 CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
105   GpuDataManager::GetInstance()->RemoveObserver(this);
107   if (!poisoned_) {
108     DCHECK(window_map()->find(window_number_) != window_map()->end());
109     DCHECK(window_map()->find(window_number_)->second == this);
110     window_map()->erase(window_number_);
111   } else {
112     WindowMap::const_iterator found = window_map()->find(window_number_);
113     if (found != window_map()->end())
114       DCHECK(found->second != this);
115   }
118 void CompositingIOSurfaceContext::OnGpuSwitching() {
119   // Recreate all browser-side GL contexts whenever the GPU switches. If this
120   // is not done, performance will suffer.
121   // http://crbug.com/361493
122   PoisonContextAndSharegroup();
125 // static
126 CompositingIOSurfaceContext::WindowMap*
127     CompositingIOSurfaceContext::window_map() {
128   return window_map_.Pointer();
131 // static
132 base::LazyInstance<CompositingIOSurfaceContext::WindowMap>
133     CompositingIOSurfaceContext::window_map_;
135 }  // namespace content