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/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_osmesa.h"
     14 #include "ui/gl/gl_context_stub.h"
     15 #include "ui/gl/gl_implementation.h"
     16 #include "ui/gl/gl_surface.h"
     17 
     18 namespace gfx {
     19 
     20 namespace {
     21 
     22 // Used to render into an already current context+surface,
     23 // that we do not have ownership of (draw callback).
     24 // TODO(boliu): Make this inherit from GLContextEGL.
     25 class GLNonOwnedContext : public GLContextReal {
     26  public:
     27   GLNonOwnedContext(GLShareGroup* share_group);
     28 
     29   // Implement GLContext.
     30   virtual bool Initialize(GLSurface* compatible_surface,
     31                           GpuPreference gpu_preference) OVERRIDE;
     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   EGLDisplay display_;
     47 };
     48 
     49 GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group)
     50   : GLContextReal(share_group), display_(NULL) {}
     51 
     52 bool GLNonOwnedContext::Initialize(GLSurface* compatible_surface,
     53                         GpuPreference gpu_preference) {
     54   display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     55   return true;
     56 }
     57 
     58 bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) {
     59   SetCurrent(surface);
     60   SetRealGLApi();
     61   return true;
     62 }
     63 
     64 std::string GLNonOwnedContext::GetExtensions() {
     65   const char* extensions = eglQueryString(display_, EGL_EXTENSIONS);
     66   if (!extensions)
     67     return GLContext::GetExtensions();
     68 
     69   return GLContext::GetExtensions() + " " + extensions;
     70 }
     71 
     72 }  // anonymous namespace
     73 
     74 // static
     75 scoped_refptr<GLContext> GLContext::CreateGLContext(
     76     GLShareGroup* share_group,
     77     GLSurface* compatible_surface,
     78     GpuPreference gpu_preference) {
     79   scoped_refptr<GLContext> context;
     80   switch (GetGLImplementation()) {
     81     case kGLImplementationMockGL:
     82       return scoped_refptr<GLContext>(new GLContextStub());
     83     case kGLImplementationOSMesaGL:
     84       context = new GLContextOSMesa(share_group);
     85       break;
     86     default:
     87       if (compatible_surface->GetHandle())
     88         context = new GLContextEGL(share_group);
     89       else
     90         context = new GLNonOwnedContext(share_group);
     91       break;
     92   }
     93 
     94   if (!context->Initialize(compatible_surface, gpu_preference))
     95     return NULL;
     96 
     97   return context;
     98 }
     99 
    100 bool GLContextEGL::GetTotalGpuMemory(size_t* bytes) {
    101   DCHECK(bytes);
    102   *bytes = 0;
    103 
    104   // We can't query available GPU memory from the system on Android.
    105   // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
    106   // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
    107   // 128MB java heap size). First we estimate physical memory using both.
    108   size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
    109   size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
    110   size_t physical_memory_mb = 0;
    111   if (dalvik_mb >= 256)
    112     physical_memory_mb = dalvik_mb * 4;
    113   else
    114     physical_memory_mb = std::max(dalvik_mb * 4,
    115                                   (physical_mb * 4) / 3);
    116 
    117   // Now we take a default of 1/8th of memory on high-memory devices,
    118   // and gradually scale that back for low-memory devices (to be nicer
    119   // to other apps so they don't get killed). Examples:
    120   // Nexus 4/10(2GB)    256MB (normally 128MB)
    121   // Droid Razr M(1GB)  114MB (normally 57MB)
    122   // Galaxy Nexus(1GB)  100MB (normally 50MB)
    123   // Xoom(1GB)          100MB (normally 50MB)
    124   // Nexus S(low-end)   12MB (normally 8MB)
    125   // Note that the compositor now uses only some of this memory for
    126   // pre-painting and uses the rest only for 'emergencies'.
    127   static size_t limit_bytes = 0;
    128   if (limit_bytes == 0) {
    129     // NOTE: Non-low-end devices use only 50% of these limits,
    130     // except during 'emergencies' where 100% can be used.
    131     if (!base::android::SysUtils::IsLowEndDevice()) {
    132       if (physical_memory_mb >= 1536)
    133         limit_bytes = physical_memory_mb / 8; // >192MB
    134       else if (physical_memory_mb >= 1152)
    135         limit_bytes = physical_memory_mb / 8; // >144MB
    136       else if (physical_memory_mb >= 768)
    137         limit_bytes = physical_memory_mb / 10; // >76MB
    138       else
    139         limit_bytes = physical_memory_mb / 12; // <64MB
    140     } else {
    141       // Low-end devices have 512MB or less memory by definition
    142       // so we hard code the limit rather than relying on the heuristics
    143       // above. Low-end devices use 4444 textures so we can use a lower limit.
    144       // NOTE: Low-end uses 2/3 (67%) of this memory in practice, so we have
    145       // increased the limit to 12 (8MB, or 12MB in emergencies).
    146       limit_bytes = 12;
    147     }
    148     limit_bytes = limit_bytes * 1024 * 1024;
    149   }
    150   *bytes = limit_bytes;
    151   return true;
    152 }
    153 
    154 }
    155