Home | History | Annotate | Download | only in gl
      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