1// Copyright (c) 2012 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_context.h" 6 7#include "base/logging.h" 8#include "base/memory/ref_counted.h" 9#include "base/sys_info.h" 10#include "ui/gl/gl_bindings.h" 11#include "ui/gl/gl_context_egl.h" 12#include "ui/gl/gl_context_osmesa.h" 13#include "ui/gl/gl_context_stub.h" 14#include "ui/gl/gl_implementation.h" 15#include "ui/gl/gl_surface.h" 16 17namespace gfx { 18 19namespace { 20 21// Used to render into an already current context+surface, 22// that we do not have ownership of (draw callback). 23// TODO(boliu): Make this inherit from GLContextEGL. 24class GLNonOwnedContext : public GLContextReal { 25 public: 26 GLNonOwnedContext(GLShareGroup* share_group); 27 28 // Implement GLContext. 29 virtual bool Initialize(GLSurface* compatible_surface, 30 GpuPreference gpu_preference) OVERRIDE; 31 virtual void Destroy() OVERRIDE {} 32 virtual bool MakeCurrent(GLSurface* surface) OVERRIDE; 33 virtual void ReleaseCurrent(GLSurface* surface) OVERRIDE {} 34 virtual bool IsCurrent(GLSurface* surface) OVERRIDE { return true; } 35 virtual void* GetHandle() OVERRIDE { return NULL; } 36 virtual void SetSwapInterval(int interval) OVERRIDE {} 37 virtual std::string GetExtensions() OVERRIDE; 38 39 protected: 40 virtual ~GLNonOwnedContext() {} 41 42 private: 43 DISALLOW_COPY_AND_ASSIGN(GLNonOwnedContext); 44 45 EGLDisplay display_; 46}; 47 48GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group) 49 : GLContextReal(share_group), display_(NULL) {} 50 51bool GLNonOwnedContext::Initialize(GLSurface* compatible_surface, 52 GpuPreference gpu_preference) { 53 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); 54 return true; 55} 56 57bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) { 58 SetCurrent(surface); 59 SetRealGLApi(); 60 return true; 61} 62 63std::string GLNonOwnedContext::GetExtensions() { 64 const char* extensions = eglQueryString(display_, EGL_EXTENSIONS); 65 if (!extensions) 66 return GLContext::GetExtensions(); 67 68 return GLContext::GetExtensions() + " " + extensions; 69} 70 71} // anonymous namespace 72 73// static 74scoped_refptr<GLContext> GLContext::CreateGLContext( 75 GLShareGroup* share_group, 76 GLSurface* compatible_surface, 77 GpuPreference gpu_preference) { 78 scoped_refptr<GLContext> context; 79 switch (GetGLImplementation()) { 80 case kGLImplementationMockGL: 81 return scoped_refptr<GLContext>(new GLContextStub()); 82 case kGLImplementationOSMesaGL: 83 context = new GLContextOSMesa(share_group); 84 break; 85 default: 86 if (compatible_surface->GetHandle()) 87 context = new GLContextEGL(share_group); 88 else 89 context = new GLNonOwnedContext(share_group); 90 break; 91 } 92 93 if (!context->Initialize(compatible_surface, gpu_preference)) 94 return NULL; 95 96 return context; 97} 98 99bool GLContextEGL::GetTotalGpuMemory(size_t* bytes) { 100 DCHECK(bytes); 101 *bytes = 0; 102 103 // We can't query available GPU memory from the system on Android. 104 // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports 105 // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports 106 // 128MB java heap size). First we estimate physical memory using both. 107 size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB(); 108 size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); 109 size_t physical_memory_mb = 0; 110 if (dalvik_mb >= 256) 111 physical_memory_mb = dalvik_mb * 4; 112 else 113 physical_memory_mb = std::max(dalvik_mb * 4, 114 (physical_mb * 4) / 3); 115 116 // Now we take a default of 1/8th of memory on high-memory devices, 117 // and gradually scale that back for low-memory devices (to be nicer 118 // to other apps so they don't get killed). Examples: 119 // Nexus 4/10(2GB) 256MB (normally 128MB) 120 // Droid Razr M(1GB) 114MB (normally 57MB) 121 // Galaxy Nexus(1GB) 100MB (normally 50MB) 122 // Xoom(1GB) 100MB (normally 50MB) 123 // Nexus S(low-end) 12MB (normally 8MB) 124 // Note that the compositor now uses only some of this memory for 125 // pre-painting and uses the rest only for 'emergencies'. 126 static size_t limit_bytes = 0; 127 if (limit_bytes == 0) { 128 // NOTE: Non-low-end devices use only 50% of these limits, 129 // except during 'emergencies' where 100% can be used. 130 if (!base::SysInfo::IsLowEndDevice()) { 131 if (physical_memory_mb >= 1536) 132 limit_bytes = physical_memory_mb / 8; // >192MB 133 else if (physical_memory_mb >= 1152) 134 limit_bytes = physical_memory_mb / 8; // >144MB 135 else if (physical_memory_mb >= 768) 136 limit_bytes = physical_memory_mb / 10; // >76MB 137 else 138 limit_bytes = physical_memory_mb / 12; // <64MB 139 } else { 140 // Low-end devices have 512MB or less memory by definition 141 // so we hard code the limit rather than relying on the heuristics 142 // above. Low-end devices use 4444 textures so we can use a lower limit. 143 // NOTE: Low-end uses 2/3 (67%) of this memory in practice, so we have 144 // increased the limit to 12 (8MB, or 12MB in emergencies). 145 limit_bytes = 12; 146 } 147 limit_bytes = limit_bytes * 1024 * 1024; 148 } 149 *bytes = limit_bytes; 150 return true; 151} 152 153} 154