浏览代码

Merge pull request #209 from Unity-Technologies/fix_gl_context_issue

use a gl context pool to provide glcontext objects to multiple panels
/main
GitHub 3 年前
当前提交
318e7c75
共有 8 个文件被更改,包括 147 次插入33 次删除
  1. 2
      engine/src/shell/platform/unity/darwin/ios/uiwidgets_system.mm
  2. 24
      engine/src/shell/platform/unity/darwin/ios/unity_surface_manager.h
  3. 44
      engine/src/shell/platform/unity/darwin/ios/unity_surface_manager.mm
  4. 2
      engine/src/shell/platform/unity/darwin/macos/uiwidgets_system.mm
  5. 24
      engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.h
  6. 84
      engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm

2
engine/src/shell/platform/unity/darwin/ios/uiwidgets_system.mm


unity_uiwidgets_->SetWakeUpCallback(nullptr);
unity_uiwidgets_ = nullptr;
UnitySurfaceManager::ReleaseResource();
unity_interfaces_ = nullptr;
}

24
engine/src/shell/platform/unity/darwin/ios/unity_surface_manager.h


#pragma once
#include <vector>
#include <OpenGLES/EAGL.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>

#include "flutter/fml/macros.h"
namespace uiwidgets {
struct GLContextPair
{
EAGLContext *gl_context_;
EAGLContext *gl_resource_context_;
GLContextPair(EAGLContext* gl, EAGLContext* gl_resource)
{
gl_context_ = gl;
gl_resource_context_ = gl_resource;
}
};
//openGLES contexts
static EAGLContext *gl_context_;
static EAGLContext *gl_resource_context_;
//openGL contexts pool
static std::vector<GLContextPair> gl_context_pool_;
static void ReleaseResource();
void* CreateRenderTexture(size_t width, size_t height);

uint32_t GetFbo();
private:
static GLContextPair GetFreeOpenGLContext();
void RecycleOpenGLContext(EAGLContext* gl, EAGLContext* gl_resource);
EAGLContext *gl_context_;
EAGLContext *gl_resource_context_;
GLuint default_fbo_ = 0;
GLuint gl_tex_ = 0;
CVOpenGLESTextureCacheRef gl_tex_cache_ref_ = nullptr;

44
engine/src/shell/platform/unity/darwin/ios/unity_surface_manager.mm


namespace uiwidgets {
EAGLContext* UnitySurfaceManager::gl_context_ = nullptr;
EAGLContext* UnitySurfaceManager::gl_resource_context_ = nullptr;
std::vector<GLContextPair> UnitySurfaceManager::gl_context_pool_;
GLContextPair UnitySurfaceManager::GetFreeOpenGLContext()
{
if (gl_context_pool_.size() == 0)
{
EAGLContext* gl = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
EAGLContext* gl_resource = [[EAGLContext alloc] initWithAPI:[gl API] sharegroup: [gl sharegroup]];
return GLContextPair(gl, gl_resource);
}
auto context_pair = gl_context_pool_.back();
gl_context_pool_.pop_back();
return context_pair;
}
void UnitySurfaceManager::RecycleOpenGLContext(EAGLContext* gl, EAGLContext* gl_resource)
{
MakeCurrentContext();
ClearCurrentContext();
MakeCurrentResourceContext();
ClearCurrentContext();
gl_context_pool_.push_back(GLContextPair(gl, gl_resource));
}
void UnitySurfaceManager::ReleaseResource()
{
while(gl_context_pool_.size() > 0)
{
gl_context_pool_.pop_back();
}
}
UnitySurfaceManager::UnitySurfaceManager(IUnityInterfaces* unity_interfaces)
{

//create opengl context
if (gl_context_ == nullptr && gl_resource_context_ == nullptr) {
gl_context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
gl_resource_context_ = [[EAGLContext alloc] initWithAPI:[gl_context_ API] sharegroup: [gl_context_ sharegroup]];
auto new_context = GetFreeOpenGLContext();
gl_context_ = new_context.gl_context_;
gl_resource_context_ = new_context.gl_resource_context_;
}
FML_DCHECK(gl_context_ != nullptr && gl_resource_context_ != nullptr);

void UnitySurfaceManager::ReleaseNativeRenderContext()
{
FML_DCHECK(gl_resource_context_);
RecycleOpenGLContext(gl_context_, gl_resource_context_);
gl_context_ = nullptr;
gl_resource_context_ = nullptr;
[EAGLContext setCurrentContext:nil];

2
engine/src/shell/platform/unity/darwin/macos/uiwidgets_system.mm


unity_uiwidgets_->SetWakeUpCallback(nullptr);
unity_uiwidgets_ = nullptr;
UnitySurfaceManager::ReleaseResource();
unity_interfaces_ = nullptr;
}

24
engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.h


#include <AppKit/AppKit.h>
#include <Metal/Metal.h>
#include <CoreVideo/CoreVideo.h>
#include <vector>
struct GLContextPair
{
NSOpenGLContext *gl_context_;
NSOpenGLContext *gl_resource_context_;
GLContextPair(NSOpenGLContext* gl, NSOpenGLContext* gl_resource)
{
gl_context_ = gl;
gl_resource_context_ = gl_resource;
}
};
//openGL contexts
static NSOpenGLContext *gl_context_;
static NSOpenGLContext *gl_resource_context_;
//openGL contexts pool
static std::vector<GLContextPair> gl_context_pool_;
static void ReleaseResource();
void* CreateRenderTexture(size_t width, size_t height);

uint32_t GetFbo();
private:
static GLContextPair GetFreeOpenGLContext();
void RecycleOpenGLContext(NSOpenGLContext* gl, NSOpenGLContext* gl_resource);
NSOpenGLContext *gl_context_;
NSOpenGLContext *gl_resource_context_;
GLuint default_fbo_ = 0;
GLuint gl_tex_ = 0;
CVOpenGLTextureCacheRef gl_tex_cache_ref_ = nullptr;

84
engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm


namespace uiwidgets {
NSOpenGLContext* UnitySurfaceManager::gl_context_ = nullptr;
NSOpenGLContext* UnitySurfaceManager::gl_resource_context_ = nullptr;
std::vector<GLContextPair> UnitySurfaceManager::gl_context_pool_;
GLContextPair UnitySurfaceManager::GetFreeOpenGLContext()
{
if (gl_context_pool_.size() == 0)
{
NSOpenGLPixelFormatAttribute attrs[] =
{
NSOpenGLPFAAccelerated,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
NSOpenGLContext* gl_resource;
NSOpenGLContext* gl;
while(gl_resource == nil) {
gl = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
gl_resource = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:gl];
if (gl_resource == nil) {
CGLReleaseContext([gl CGLContextObj]);
gl = nullptr;
}
}
return GLContextPair(gl, gl_resource);
}
auto context_pair = gl_context_pool_.back();
gl_context_pool_.pop_back();
return context_pair;
}
void UnitySurfaceManager::RecycleOpenGLContext(NSOpenGLContext* gl, NSOpenGLContext* gl_resource)
{
MakeCurrentContext();
ClearCurrentContext();
MakeCurrentResourceContext();
ClearCurrentContext();
gl_context_pool_.push_back(GLContextPair(gl, gl_resource));
}
void UnitySurfaceManager::ReleaseResource()
{
while(gl_context_pool_.size() > 0)
{
auto context_pair = gl_context_pool_.back();
CGLReleaseContext([context_pair.gl_context_ CGLContextObj]);
CGLReleaseContext([context_pair.gl_resource_context_ CGLContextObj]);
gl_context_pool_.pop_back();
}
}
UnitySurfaceManager::UnitySurfaceManager(IUnityInterfaces* unity_interfaces)
{

//create opengl context
if (gl_context_ == nullptr && gl_resource_context_ == nullptr) {
NSOpenGLPixelFormatAttribute attrs[] =
{
NSOpenGLPFAAccelerated,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
//gl_context_ may be created unproperly, we can check this using the relevant gl_resource_context_
//loop until the created gl_context_ is ok, otherwise the program will crash anyway
while(gl_resource_context_ == nil) {
gl_context_ = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
gl_resource_context_ = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:gl_context_];
if (gl_resource_context_ == nil) {
CGLReleaseContext(gl_context_.CGLContextObj);
gl_context_ = nullptr;
}
}
auto new_context = GetFreeOpenGLContext();
gl_context_ = new_context.gl_context_;
gl_resource_context_ = new_context.gl_resource_context_;
}
FML_DCHECK(gl_context_ != nullptr && gl_resource_context_ != nullptr);

void UnitySurfaceManager::ReleaseNativeRenderContext()
{
FML_DCHECK(gl_resource_context_);
FML_DCHECK(gl_context_);
FML_DCHECK(gl_context_);
RecycleOpenGLContext(gl_context_, gl_resource_context_);
gl_context_ = nullptr;
gl_resource_context_ = nullptr;
FML_DCHECK(metal_device_ != nullptr);
metal_device_ = nullptr;

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存