mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
152 lines
4.9 KiB
C++
152 lines
4.9 KiB
C++
// 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.
|
|
bool Initialize(GLSurface* compatible_surface,
|
|
GpuPreference gpu_preference) override;
|
|
void Destroy() override {}
|
|
bool MakeCurrent(GLSurface* surface) override;
|
|
void ReleaseCurrent(GLSurface* surface) override {}
|
|
bool IsCurrent(GLSurface* surface) override { return true; }
|
|
void* GetHandle() override { return NULL; }
|
|
void OnSetSwapInterval(int interval) override {}
|
|
std::string GetExtensions() override;
|
|
|
|
protected:
|
|
~GLNonOwnedContext() override {}
|
|
|
|
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;
|
|
}
|
|
|
|
}
|