mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
132 lines
4.3 KiB
C++
132 lines
4.3 KiB
C++
// 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/platform/windows/external_texture_gl.h"
|
|
|
|
#include <EGL/egl.h>
|
|
#include <GLES2/gl2.h>
|
|
#include <GLES2/gl2ext.h>
|
|
|
|
namespace {
|
|
|
|
typedef void (*glGenTexturesProc)(GLsizei n, GLuint* textures);
|
|
typedef void (*glDeleteTexturesProc)(GLsizei n, const GLuint* textures);
|
|
typedef void (*glBindTextureProc)(GLenum target, GLuint texture);
|
|
typedef void (*glTexParameteriProc)(GLenum target, GLenum pname, GLint param);
|
|
typedef void (*glTexImage2DProc)(GLenum target,
|
|
GLint level,
|
|
GLint internalformat,
|
|
GLsizei width,
|
|
GLsizei height,
|
|
GLint border,
|
|
GLenum format,
|
|
GLenum type,
|
|
const void* data);
|
|
|
|
// A struct containing pointers to resolved gl* functions.
|
|
struct GlProcs {
|
|
glGenTexturesProc glGenTextures;
|
|
glDeleteTexturesProc glDeleteTextures;
|
|
glBindTextureProc glBindTexture;
|
|
glTexParameteriProc glTexParameteri;
|
|
glTexImage2DProc glTexImage2D;
|
|
bool valid;
|
|
};
|
|
|
|
static const GlProcs& GlProcs() {
|
|
static struct GlProcs procs = {};
|
|
static bool initialized = false;
|
|
if (!initialized) {
|
|
procs.glGenTextures =
|
|
reinterpret_cast<glGenTexturesProc>(eglGetProcAddress("glGenTextures"));
|
|
procs.glDeleteTextures = reinterpret_cast<glDeleteTexturesProc>(
|
|
eglGetProcAddress("glDeleteTextures"));
|
|
procs.glBindTexture =
|
|
reinterpret_cast<glBindTextureProc>(eglGetProcAddress("glBindTexture"));
|
|
procs.glTexParameteri = reinterpret_cast<glTexParameteriProc>(
|
|
eglGetProcAddress("glTexParameteri"));
|
|
procs.glTexImage2D =
|
|
reinterpret_cast<glTexImage2DProc>(eglGetProcAddress("glTexImage2D"));
|
|
|
|
procs.valid = procs.glGenTextures && procs.glDeleteTextures &&
|
|
procs.glBindTexture && procs.glTexParameteri &&
|
|
procs.glTexImage2D;
|
|
initialized = true;
|
|
}
|
|
return procs;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace flutter {
|
|
|
|
struct ExternalTextureGLState {
|
|
GLuint gl_texture = 0;
|
|
};
|
|
|
|
ExternalTextureGL::ExternalTextureGL(
|
|
FlutterDesktopPixelBufferTextureCallback texture_callback,
|
|
void* user_data)
|
|
: state_(std::make_unique<ExternalTextureGLState>()),
|
|
texture_callback_(texture_callback),
|
|
user_data_(user_data) {}
|
|
|
|
ExternalTextureGL::~ExternalTextureGL() {
|
|
const auto& gl = GlProcs();
|
|
if (gl.valid && state_->gl_texture != 0) {
|
|
gl.glDeleteTextures(1, &state_->gl_texture);
|
|
}
|
|
}
|
|
|
|
bool ExternalTextureGL::PopulateTexture(size_t width,
|
|
size_t height,
|
|
FlutterOpenGLTexture* opengl_texture) {
|
|
if (!CopyPixelBuffer(width, height)) {
|
|
return false;
|
|
}
|
|
|
|
// Populate the texture object used by the engine.
|
|
opengl_texture->target = GL_TEXTURE_2D;
|
|
opengl_texture->name = state_->gl_texture;
|
|
opengl_texture->format = GL_RGBA8;
|
|
opengl_texture->destruction_callback = nullptr;
|
|
opengl_texture->user_data = nullptr;
|
|
opengl_texture->width = width;
|
|
opengl_texture->height = height;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ExternalTextureGL::CopyPixelBuffer(size_t& width, size_t& height) {
|
|
const FlutterDesktopPixelBuffer* pixel_buffer =
|
|
texture_callback_(width, height, user_data_);
|
|
const auto& gl = GlProcs();
|
|
if (!gl.valid || !pixel_buffer || !pixel_buffer->buffer) {
|
|
return false;
|
|
}
|
|
width = pixel_buffer->width;
|
|
height = pixel_buffer->height;
|
|
|
|
if (state_->gl_texture == 0) {
|
|
gl.glGenTextures(1, &state_->gl_texture);
|
|
|
|
gl.glBindTexture(GL_TEXTURE_2D, state_->gl_texture);
|
|
|
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
|
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
} else {
|
|
gl.glBindTexture(GL_TEXTURE_2D, state_->gl_texture);
|
|
}
|
|
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width,
|
|
pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
pixel_buffer->buffer);
|
|
return true;
|
|
}
|
|
|
|
} // namespace flutter
|