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