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 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 if (GetGLImplementation() == kGLImplementationMockGL) 79 return scoped_refptr<GLContext>(new GLContextStub()); 80 81 scoped_refptr<GLContext> context; 82 if (compatible_surface->GetHandle()) 83 context = new GLContextEGL(share_group); 84 else 85 context = new GLNonOwnedContext(share_group); 86 if (!context->Initialize(compatible_surface, gpu_preference)) 87 return NULL; 88 return context; 89} 90 91bool GLContextEGL::GetTotalGpuMemory(size_t* bytes) { 92 DCHECK(bytes); 93 *bytes = 0; 94 95 // We can't query available GPU memory from the system on Android. 96 // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports 97 // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports 98 // 128MB java heap size). First we estimate physical memory using both. 99 size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB(); 100 size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); 101 size_t physical_memory_mb = 0; 102 if (dalvik_mb >= 256) 103 physical_memory_mb = dalvik_mb * 4; 104 else 105 physical_memory_mb = std::max(dalvik_mb * 4, 106 (physical_mb * 4) / 3); 107 108 // Now we take a default of 1/8th of memory on high-memory devices, 109 // and gradually scale that back for low-memory devices (to be nicer 110 // to other apps so they don't get killed). Examples: 111 // Nexus 4/10(2GB) 256MB 112 // Droid Razr M(1GB) 91MB 113 // Galaxy Nexus(1GB) 85MB 114 // Xoom(1GB) 85MB 115 // Nexus S(low-end) 8MB 116 static size_t limit_bytes = 0; 117 if (limit_bytes == 0) { 118 if (!base::android::SysUtils::IsLowEndDevice()) { 119 if (physical_memory_mb >= 1536) 120 limit_bytes = physical_memory_mb / 8; 121 else if (physical_memory_mb >= 1152) 122 limit_bytes = physical_memory_mb / 10; 123 else if (physical_memory_mb >= 768) 124 limit_bytes = physical_memory_mb / 12; 125 else 126 limit_bytes = physical_memory_mb / 16; 127 } else { 128 // Low-end devices have 512MB or less memory by definition 129 // so we hard code the limit rather than relying on the heuristics 130 // above. Low-end devices use 4444 textures so we can use a lower limit. 131 limit_bytes = 8; 132 } 133 limit_bytes = limit_bytes * 1024 * 1024; 134 } 135 *bytes = limit_bytes; 136 return true; 137} 138 139} 140