提交 37a1d873 编写于 作者: C Chinmay Garde 提交者: GitHub

Fallback to creating Skia managed images on platforms that dont provide a GL...

Fallback to creating Skia managed images on platforms that dont provide a GL context on the resource loader. (#2849)
上级 a415e0e7
......@@ -9,6 +9,18 @@
namespace flow {
enum class TextureImageFormat {
Grey,
GreyAlpha,
RGB,
RGBA,
};
enum class TextureImageDataFormat {
UnsignedByte,
UnsignedShort565,
};
static inline GLint ToGLFormat(TextureImageFormat format) {
switch (format) {
case TextureImageFormat::RGBA:
......@@ -56,7 +68,81 @@ static inline SkColorType ToSkColorType(TextureImageFormat format) {
return kRGB_565_SkColorType;
}
sk_sp<SkImage> TextureImageCreate(GrContext* context, const SkBitmap& bitmap) {
static sk_sp<SkImage> TextureImageCreate(GrContext* context,
TextureImageFormat format,
const SkISize& size,
TextureImageDataFormat dataFormat,
const uint8_t* data) {
TRACE_EVENT2("flutter", __func__, "width", size.width(), "height",
size.height());
if (context == nullptr) {
return nullptr;
}
GLuint handle = GL_NONE;
// Generate the texture handle.
glGenTextures(1, &handle);
// Bind the texture.
glBindTexture(GL_TEXTURE_2D, handle);
// Specify default texture properties.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Update unpack alignment based on format.
glPixelStorei(GL_UNPACK_ALIGNMENT,
dataFormat == TextureImageDataFormat::UnsignedByte ? 4 : 2);
GLint gl_format = ToGLFormat(format);
// Upload the texture.
glTexImage2D(GL_TEXTURE_2D, // target
0, // level
gl_format, // internal format
size.fWidth, // width
size.fHeight, // height
0, // border
gl_format, // format
ToGLDataFormat(dataFormat), // format
data);
// Clear the binding. We are done.
glBindTexture(GL_TEXTURE_2D, GL_NONE);
GrGLTextureInfo texInfo;
texInfo.fTarget = GL_TEXTURE_2D;
texInfo.fID = handle;
// Create an SkImage handle from the texture.
GrBackendTextureDesc desc;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fFlags = kNone_GrBackendTextureFlag;
desc.fWidth = size.fWidth;
desc.fHeight = size.fHeight;
desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&texInfo);
desc.fConfig = ToGrPixelConfig(dataFormat);
if (auto image = SkImage::MakeFromAdoptedTexture(context, desc)) {
// Texture handle was successfully adopted by the SkImage.
return image;
}
// We could not create an SkImage from the texture. Since it could not be
// adopted, delete the handle and return null.
glDeleteTextures(1, &handle);
return nullptr;
}
static sk_sp<SkImage> TextureImageCreate(GrContext* context,
const SkBitmap& bitmap) {
if (context == nullptr) {
return nullptr;
}
......@@ -91,13 +177,23 @@ sk_sp<SkImage> TextureImageCreate(GrContext* context, const SkBitmap& bitmap) {
);
}
sk_sp<SkImage> BitmapImageCreate(SkImageGenerator& generator) {
SkBitmap bitmap;
if (generator.tryGenerateBitmap(&bitmap)) {
return SkImage::MakeFromBitmap(bitmap);
}
return nullptr;
}
sk_sp<SkImage> TextureImageCreate(GrContext* context,
std::unique_ptr<SkImageGenerator> generator) {
if (context == nullptr || generator == nullptr) {
SkImageGenerator& generator) {
if (context == nullptr) {
return nullptr;
}
const SkImageInfo& info = generator->getInfo();
const SkImageInfo& info = generator.getInfo();
if (info.isEmpty()) {
return nullptr;
......@@ -123,7 +219,7 @@ sk_sp<SkImage> TextureImageCreate(GrContext* context,
TRACE_EVENT1("flutter", "DecodePrimaryPreferrence", "Type",
preferOpaque ? "RGB565" : "RGBA8888");
// Try our preferred config.
if (generator->tryGenerateBitmap(&bitmap, preferredImageInfo, nullptr)) {
if (generator.tryGenerateBitmap(&bitmap, preferredImageInfo, nullptr)) {
// Our got our preferred bitmap.
return TextureImageCreate(context, bitmap);
}
......@@ -132,7 +228,7 @@ sk_sp<SkImage> TextureImageCreate(GrContext* context,
{
TRACE_EVENT0("flutter", "DecodeRecommended");
// Try the guessed config.
if (generator->tryGenerateBitmap(&bitmap)) {
if (generator.tryGenerateBitmap(&bitmap)) {
return TextureImageCreate(context, bitmap);
}
}
......@@ -140,77 +236,4 @@ sk_sp<SkImage> TextureImageCreate(GrContext* context,
return nullptr;
}
sk_sp<SkImage> TextureImageCreate(GrContext* context,
TextureImageFormat format,
const SkISize& size,
TextureImageDataFormat dataFormat,
const uint8_t* data) {
TRACE_EVENT2("flutter", __func__, "width", size.width(), "height",
size.height());
if (context == nullptr) {
return nullptr;
}
GLuint handle = GL_NONE;
// Generate the texture handle.
glGenTextures(1, &handle);
// Bind the texture.
glBindTexture(GL_TEXTURE_2D, handle);
// Specify default texture properties.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Update unpack alignment based on format.
glPixelStorei(GL_UNPACK_ALIGNMENT,
dataFormat == TextureImageDataFormat::UnsignedByte ? 4 : 2);
GLint gl_format = ToGLFormat(format);
// Upload the texture.
glTexImage2D(GL_TEXTURE_2D, // target
0, // level
gl_format, // internal format
size.fWidth, // width
size.fHeight, // height
0, // border
gl_format, // format
ToGLDataFormat(dataFormat), // format
data);
// Clear the binding. We are done.
glBindTexture(GL_TEXTURE_2D, GL_NONE);
GrGLTextureInfo texInfo;
texInfo.fTarget = GL_TEXTURE_2D;
texInfo.fID = handle;
// Create an SkImage handle from the texture.
GrBackendTextureDesc desc;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fFlags = kNone_GrBackendTextureFlag;
desc.fWidth = size.fWidth;
desc.fHeight = size.fHeight;
desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&texInfo);
desc.fConfig = ToGrPixelConfig(dataFormat);
if (auto image = SkImage::MakeFromAdoptedTexture(context, desc)) {
// Texture handle was successfully adopted by the SkImage.
return image;
}
// We could not create an SkImage from the texture. Since it could not be
// adopted, delete the handle and return null.
glDeleteTextures(1, &handle);
return nullptr;
}
} // namespace flow
......@@ -10,28 +10,10 @@
namespace flow {
enum class TextureImageFormat {
Grey,
GreyAlpha,
RGB,
RGBA,
};
enum class TextureImageDataFormat {
UnsignedByte,
UnsignedShort565,
};
sk_sp<SkImage> TextureImageCreate(GrContext* context, const SkBitmap& bitmap);
sk_sp<SkImage> TextureImageCreate(GrContext* context,
std::unique_ptr<SkImageGenerator> generator);
SkImageGenerator& generator);
sk_sp<SkImage> TextureImageCreate(GrContext* context,
TextureImageFormat format,
const SkISize& size,
TextureImageDataFormat dataFormat,
const uint8_t* data);
sk_sp<SkImage> BitmapImageCreate(SkImageGenerator& generator);
} // namespace flow
......
......@@ -48,7 +48,14 @@ sk_sp<SkImage> DecodeImage(PassRefPtr<SharedBuffer> buffer) {
auto context = reinterpret_cast<GrContext*>(
sky::shell::PlatformView::ResourceContext.Get());
return flow::TextureImageCreate(context, std::move(generator));
// First, try to create a texture image from the generator.
if (auto image = flow::TextureImageCreate(context, *generator)) {
return image;
}
// The, as a fallback, try to create a regular Skia managed image. These
// don't require a context ready.
return flow::BitmapImageCreate(*generator);
}
void InvokeImageCallback(sk_sp<SkImage> image,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册