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/android/sys_utils.h" 8 #include "base/logging.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/sys_info.h" 11 #include "ui/gl/gl_bindings.h" 12 #include "ui/gl/gl_context_egl.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 class GLNonOwnedContext : public GLContextReal { 24 public: 25 GLNonOwnedContext(GLShareGroup* share_group); 26 27 // Implement GLContext. 28 virtual bool Initialize(GLSurface* compatible_surface, 29 GpuPreference gpu_preference) OVERRIDE { 30 return true; 31 } 32 virtual void Destroy() OVERRIDE {} 33 virtual bool MakeCurrent(GLSurface* surface) OVERRIDE; 34 virtual void ReleaseCurrent(GLSurface* surface) OVERRIDE {} 35 virtual bool IsCurrent(GLSurface* surface) OVERRIDE { return true; } 36 virtual void* GetHandle() OVERRIDE { return NULL; } 37 virtual void SetSwapInterval(int interval) OVERRIDE {} 38 virtual std::string GetExtensions() OVERRIDE; 39 40 protected: 41 virtual ~GLNonOwnedContext() {} 42 43 private: 44 DISALLOW_COPY_AND_ASSIGN(GLNonOwnedContext); 45 }; 46 47 GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group) 48 : GLContextReal(share_group) {} 49 50 bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) { 51 SetCurrent(surface); 52 SetRealGLApi(); 53 return true; 54 } 55 56 std::string GLNonOwnedContext::GetExtensions() { 57 return GLContext::GetExtensions(); 58 } 59 60 } // anonymous namespace 61 62 // static 63 scoped_refptr<GLContext> GLContext::CreateGLContext( 64 GLShareGroup* share_group, 65 GLSurface* compatible_surface, 66 GpuPreference gpu_preference) { 67 if (GetGLImplementation() == kGLImplementationMockGL) 68 return scoped_refptr<GLContext>(new GLContextStub()); 69 70 scoped_refptr<GLContext> context; 71 if (compatible_surface->GetHandle()) 72 context = new GLContextEGL(share_group); 73 else 74 context = new GLNonOwnedContext(share_group); 75 if (!context->Initialize(compatible_surface, gpu_preference)) 76 return NULL; 77 return context; 78 } 79 80 bool GLContextEGL::GetTotalGpuMemory(size_t* bytes) { 81 DCHECK(bytes); 82 *bytes = 0; 83 84 // We can't query available GPU memory from the system on Android. 85 // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports 86 // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports 87 // 128MB java heap size). First we estimate physical memory using both. 88 size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB(); 89 size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); 90 size_t physical_memory_mb = 0; 91 if (dalvik_mb >= 256) 92 physical_memory_mb = dalvik_mb * 4; 93 else 94 physical_memory_mb = std::max(dalvik_mb * 4, 95 (physical_mb * 4) / 3); 96 97 // Now we take a default of 1/8th of memory on high-memory devices, 98 // and gradually scale that back for low-memory devices (to be nicer 99 // to other apps so they don't get killed). Examples: 100 // Nexus 4/10(2GB) 256MB 101 // Droid Razr M(1GB) 91MB 102 // Galaxy Nexus(1GB) 85MB 103 // Xoom(1GB) 85MB 104 // Nexus S(low-end) 16MB 105 static size_t limit_bytes = 0; 106 if (limit_bytes == 0) { 107 if (!base::android::SysUtils::IsLowEndDevice()) { 108 if (physical_memory_mb >= 1536) 109 limit_bytes = physical_memory_mb / 8; 110 else if (physical_memory_mb >= 1152) 111 limit_bytes = physical_memory_mb / 10; 112 else if (physical_memory_mb >= 768) 113 limit_bytes = physical_memory_mb / 12; 114 else 115 limit_bytes = physical_memory_mb / 16; 116 } else { 117 limit_bytes = physical_memory_mb / 32; 118 } 119 limit_bytes = limit_bytes * 1024 * 1024; 120 } 121 *bytes = limit_bytes; 122 return true; 123 } 124 125 } 126