blob: 2e737f03a9b6d99451c3dcc360f27b4a3206a009 [file] [log] [blame]
// Copyright 2013 The Flutter 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 "flutter/shell/gpu/gpu_surface_gl_delegate.h"
#include <cstring>
#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
namespace flutter {
GPUSurfaceGLDelegate::~GPUSurfaceGLDelegate() = default;
bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const {
return false;
}
SurfaceFrame::FramebufferInfo GPUSurfaceGLDelegate::GLContextFramebufferInfo()
const {
SurfaceFrame::FramebufferInfo res;
res.supports_readback = true;
return res;
}
SkMatrix GPUSurfaceGLDelegate::GLContextSurfaceTransformation() const {
SkMatrix matrix;
matrix.setIdentity();
return matrix;
}
GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver()
const {
return nullptr;
}
static bool IsProcResolverOpenGLES(
const GPUSurfaceGLDelegate::GLProcResolver& proc_resolver) {
// Version string prefix that identifies an OpenGL ES implementation.
#define GPU_GL_VERSION 0x1F02
constexpr char kGLESVersionPrefix[] = "OpenGL ES";
#ifdef WIN32
using GLGetStringProc = const char*(__stdcall*)(uint32_t);
#else
using GLGetStringProc = const char* (*)(uint32_t);
#endif
GLGetStringProc gl_get_string =
reinterpret_cast<GLGetStringProc>(proc_resolver("glGetString"));
FML_CHECK(gl_get_string)
<< "The GL proc resolver could not resolve glGetString";
const char* gl_version_string = gl_get_string(GPU_GL_VERSION);
FML_CHECK(gl_version_string)
<< "The GL proc resolver's glGetString(GL_VERSION) failed";
return strncmp(gl_version_string, kGLESVersionPrefix,
strlen(kGLESVersionPrefix)) == 0;
}
static sk_sp<const GrGLInterface> CreateGLInterface(
const GPUSurfaceGLDelegate::GLProcResolver& proc_resolver) {
if (proc_resolver == nullptr) {
// If there is no custom proc resolver, ask Skia to guess the native
// interface. This often leads to interesting results on most platforms.
return GrGLMakeNativeInterface();
}
struct ProcResolverContext {
GPUSurfaceGLDelegate::GLProcResolver resolver;
};
ProcResolverContext context = {proc_resolver};
GrGLGetProc gl_get_proc = [](void* context,
const char gl_proc_name[]) -> GrGLFuncPtr {
auto proc_resolver_context =
reinterpret_cast<ProcResolverContext*>(context);
return reinterpret_cast<GrGLFuncPtr>(
proc_resolver_context->resolver(gl_proc_name));
};
// glGetString indicates an OpenGL ES interface.
if (IsProcResolverOpenGLES(proc_resolver)) {
return GrGLMakeAssembledGLESInterface(&context, gl_get_proc);
}
// Fallback to OpenGL.
if (auto interface = GrGLMakeAssembledGLInterface(&context, gl_get_proc)) {
return interface;
}
FML_LOG(ERROR) << "Could not create a valid GL interface.";
return nullptr;
}
sk_sp<const GrGLInterface> GPUSurfaceGLDelegate::GetGLInterface() const {
return CreateGLInterface(GetGLProcResolver());
}
sk_sp<const GrGLInterface>
GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() {
return CreateGLInterface(nullptr);
}
bool GPUSurfaceGLDelegate::AllowsDrawingWhenGpuDisabled() const {
return true;
}
} // namespace flutter