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 17 namespace gfx { 18 19 namespace { 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. 24 class 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 48 GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group) 49 : GLContextReal(share_group), display_(NULL) {} 50 51 bool GLNonOwnedContext::Initialize(GLSurface* compatible_surface, 52 GpuPreference gpu_preference) { 53 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); 54 return true; 55 } 56 57 bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) { 58 SetCurrent(surface); 59 SetRealGLApi(); 60 return true; 61 } 62 63 std::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 74 scoped_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 99 bool 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