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_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