15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_info.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context_egl.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gl/gl_context_osmesa.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context_stub.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_surface.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to render into an already current context+surface, 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that we do not have ownership of (draw callback). 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// TODO(boliu): Make this inherit from GLContextEGL. 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class GLNonOwnedContext : public GLContextReal { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GLNonOwnedContext(GLShareGroup* share_group); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Implement GLContext. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool Initialize(GLSurface* compatible_surface, 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GpuPreference gpu_preference) OVERRIDE; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Destroy() OVERRIDE {} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool MakeCurrent(GLSurface* surface) OVERRIDE; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ReleaseCurrent(GLSurface* surface) OVERRIDE {} 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsCurrent(GLSurface* surface) OVERRIDE { return true; } 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void* GetHandle() OVERRIDE { return NULL; } 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetSwapInterval(int interval) OVERRIDE {} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetExtensions() OVERRIDE; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~GLNonOwnedContext() {} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GLNonOwnedContext); 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EGLDisplay display_; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group) 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : GLContextReal(share_group), display_(NULL) {} 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GLNonOwnedContext::Initialize(GLSurface* compatible_surface, 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GpuPreference gpu_preference) { 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) { 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrent(surface); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRealGLApi(); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GLNonOwnedContext::GetExtensions() { 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const char* extensions = eglQueryString(display_, EGL_EXTENSIONS); 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!extensions) 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GLContext::GetExtensions(); 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GLContext::GetExtensions() + " " + extensions; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // anonymous namespace 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<GLContext> GLContext::CreateGLContext( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLShareGroup* share_group, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLSurface* compatible_surface, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuPreference gpu_preference) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<GLContext> context; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (GetGLImplementation()) { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kGLImplementationMockGL: 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_refptr<GLContext>(new GLContextStub()); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kGLImplementationOSMesaGL: 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context = new GLContextOSMesa(share_group); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (compatible_surface->GetHandle()) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context = new GLContextEGL(share_group); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context = new GLNonOwnedContext(share_group); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context->Initialize(compatible_surface, gpu_preference)) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLContextEGL::GetTotalGpuMemory(size_t* bytes) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(bytes); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *bytes = 0; 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We can't query available GPU memory from the system on Android. 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // 128MB java heap size). First we estimate physical memory using both. 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB(); 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t physical_memory_mb = 0; 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (dalvik_mb >= 256) 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) physical_memory_mb = dalvik_mb * 4; 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) physical_memory_mb = std::max(dalvik_mb * 4, 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (physical_mb * 4) / 3); 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Now we take a default of 1/8th of memory on high-memory devices, 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // and gradually scale that back for low-memory devices (to be nicer 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // to other apps so they don't get killed). Examples: 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Nexus 4/10(2GB) 256MB (normally 128MB) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Droid Razr M(1GB) 114MB (normally 57MB) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Galaxy Nexus(1GB) 100MB (normally 50MB) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Xoom(1GB) 100MB (normally 50MB) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Nexus S(low-end) 12MB (normally 8MB) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that the compositor now uses only some of this memory for 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // pre-painting and uses the rest only for 'emergencies'. 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) static size_t limit_bytes = 0; 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (limit_bytes == 0) { 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NOTE: Non-low-end devices use only 50% of these limits, 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // except during 'emergencies' where 100% can be used. 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!base::SysInfo::IsLowEndDevice()) { 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (physical_memory_mb >= 1536) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) limit_bytes = physical_memory_mb / 8; // >192MB 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else if (physical_memory_mb >= 1152) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) limit_bytes = physical_memory_mb / 8; // >144MB 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else if (physical_memory_mb >= 768) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) limit_bytes = physical_memory_mb / 10; // >76MB 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) limit_bytes = physical_memory_mb / 12; // <64MB 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Low-end devices have 512MB or less memory by definition 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // so we hard code the limit rather than relying on the heuristics 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // above. Low-end devices use 4444 textures so we can use a lower limit. 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NOTE: Low-end uses 2/3 (67%) of this memory in practice, so we have 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // increased the limit to 12 (8MB, or 12MB in emergencies). 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) limit_bytes = 12; 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) limit_bytes = limit_bytes * 1024 * 1024; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *bytes = limit_bytes; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 154