[Impeller] use device private on non-iOS devices. (#164601)
Redo of https://github.com/flutter/flutter/pull/164573 Fixes https://github.com/flutter/flutter/issues/136365 Fixes https://github.com/flutter/flutter/issues/134399 We should avoid using "host visible" textures outside of iOS, which besides arm macs, is the only place they are supported. Deletes a test that was completely invalid because it was testing a feature "the gpu sync switch aka iOS background check" that was never used in mutli_frame image codecs.
This commit is contained in:
parent
27030bb245
commit
80913c3389
@ -405,7 +405,7 @@ void ImageDecoderImpeller::UploadTextureToPrivate(
|
|||||||
const SkImageInfo& image_info,
|
const SkImageInfo& image_info,
|
||||||
const std::shared_ptr<SkBitmap>& bitmap,
|
const std::shared_ptr<SkBitmap>& bitmap,
|
||||||
const std::optional<SkImageInfo>& resize_info,
|
const std::optional<SkImageInfo>& resize_info,
|
||||||
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch) {
|
const std::shared_ptr<const fml::SyncSwitch>& gpu_disabled_switch) {
|
||||||
TRACE_EVENT0("impeller", __FUNCTION__);
|
TRACE_EVENT0("impeller", __FUNCTION__);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
result(nullptr, "No Impeller context is available");
|
result(nullptr, "No Impeller context is available");
|
||||||
|
@ -88,7 +88,7 @@ class ImageDecoderImpeller final : public ImageDecoder {
|
|||||||
const SkImageInfo& image_info,
|
const SkImageInfo& image_info,
|
||||||
const std::shared_ptr<SkBitmap>& bitmap,
|
const std::shared_ptr<SkBitmap>& bitmap,
|
||||||
const std::optional<SkImageInfo>& resize_info,
|
const std::optional<SkImageInfo>& resize_info,
|
||||||
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch);
|
const std::shared_ptr<const fml::SyncSwitch>& gpu_disabled_switch);
|
||||||
|
|
||||||
/// @brief Create a texture from the provided bitmap.
|
/// @brief Create a texture from the provided bitmap.
|
||||||
/// @param context The Impeller graphics context.
|
/// @param context The Impeller graphics context.
|
||||||
|
@ -385,6 +385,9 @@ TEST_F(ImageDecoderFixtureTest, ImpellerUploadToSharedNoGpu) {
|
|||||||
ASSERT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
|
ASSERT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
|
||||||
ASSERT_EQ(result.second, "");
|
ASSERT_EQ(result.second, "");
|
||||||
EXPECT_EQ(no_gpu_access_context->DidDisposeResources(), true);
|
EXPECT_EQ(no_gpu_access_context->DidDisposeResources(), true);
|
||||||
|
EXPECT_EQ(
|
||||||
|
result.first->impeller_texture()->GetTextureDescriptor().storage_mode,
|
||||||
|
impeller::StorageMode::kHostVisible);
|
||||||
|
|
||||||
no_gpu_access_context->FlushTasks(/*fail=*/true);
|
no_gpu_access_context->FlushTasks(/*fail=*/true);
|
||||||
}
|
}
|
||||||
@ -1007,174 +1010,6 @@ TEST_F(ImageDecoderFixtureTest,
|
|||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
|
PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ImageDecoderFixtureTest, MultiFrameCodecDidAccessGpuDisabledSyncSwitch) {
|
|
||||||
auto settings = CreateSettingsForFixture();
|
|
||||||
auto vm_ref = DartVMRef::Create(settings);
|
|
||||||
auto vm_data = vm_ref.GetVMData();
|
|
||||||
|
|
||||||
auto gif_mapping = flutter::testing::OpenFixtureAsSkData("hello_loop_2.gif");
|
|
||||||
|
|
||||||
ASSERT_TRUE(gif_mapping);
|
|
||||||
|
|
||||||
ImageGeneratorRegistry registry;
|
|
||||||
std::shared_ptr<ImageGenerator> gif_generator =
|
|
||||||
registry.CreateCompatibleGenerator(gif_mapping);
|
|
||||||
ASSERT_TRUE(gif_generator);
|
|
||||||
|
|
||||||
TaskRunners runners(GetCurrentTestName(), // label
|
|
||||||
CreateNewThread("platform"), // platform
|
|
||||||
CreateNewThread("raster"), // raster
|
|
||||||
CreateNewThread("ui"), // ui
|
|
||||||
CreateNewThread("io") // io
|
|
||||||
);
|
|
||||||
|
|
||||||
std::unique_ptr<TestIOManager> io_manager;
|
|
||||||
fml::RefPtr<MultiFrameCodec> codec;
|
|
||||||
fml::AutoResetWaitableEvent latch;
|
|
||||||
|
|
||||||
auto validate_frame_callback = [&latch](Dart_NativeArguments args) {
|
|
||||||
EXPECT_FALSE(Dart_IsNull(Dart_GetNativeArgument(args, 0)));
|
|
||||||
latch.Signal();
|
|
||||||
};
|
|
||||||
|
|
||||||
AddNativeCallback("ValidateFrameCallback",
|
|
||||||
CREATE_NATIVE_ENTRY(validate_frame_callback));
|
|
||||||
// Setup the IO manager.
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() {
|
|
||||||
io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
|
|
||||||
});
|
|
||||||
|
|
||||||
auto isolate = RunDartCodeInIsolate(vm_ref, settings, runners, "main", {},
|
|
||||||
GetDefaultKernelFilePath(),
|
|
||||||
io_manager->GetWeakIOManager());
|
|
||||||
|
|
||||||
PostTaskSync(runners.GetUITaskRunner(), [&]() {
|
|
||||||
fml::AutoResetWaitableEvent isolate_latch;
|
|
||||||
|
|
||||||
EXPECT_TRUE(isolate->RunInIsolateScope([&]() -> bool {
|
|
||||||
Dart_Handle library = Dart_RootLibrary();
|
|
||||||
if (Dart_IsError(library)) {
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Dart_Handle closure =
|
|
||||||
Dart_GetField(library, Dart_NewStringFromCString("frameCallback"));
|
|
||||||
if (Dart_IsError(closure) || !Dart_IsClosure(closure)) {
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_FALSE(io_manager->did_access_is_gpu_disabled_sync_switch_);
|
|
||||||
codec = fml::MakeRefCounted<MultiFrameCodec>(std::move(gif_generator));
|
|
||||||
codec->getNextFrame(closure);
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return true;
|
|
||||||
}));
|
|
||||||
isolate_latch.Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() {
|
|
||||||
EXPECT_TRUE(io_manager->did_access_is_gpu_disabled_sync_switch_);
|
|
||||||
});
|
|
||||||
|
|
||||||
latch.Wait();
|
|
||||||
|
|
||||||
// Destroy the Isolate
|
|
||||||
isolate = nullptr;
|
|
||||||
|
|
||||||
// Destroy the MultiFrameCodec
|
|
||||||
PostTaskSync(runners.GetUITaskRunner(), [&]() { codec = nullptr; });
|
|
||||||
|
|
||||||
// Destroy the IO manager
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ImageDecoderFixtureTest, MultiFrameCodecIsPausedWhenGPUIsUnavailable) {
|
|
||||||
auto settings = CreateSettingsForFixture();
|
|
||||||
settings.enable_impeller = true;
|
|
||||||
auto vm_ref = DartVMRef::Create(settings);
|
|
||||||
auto vm_data = vm_ref.GetVMData();
|
|
||||||
|
|
||||||
auto gif_mapping = flutter::testing::OpenFixtureAsSkData("hello_loop_2.gif");
|
|
||||||
|
|
||||||
ASSERT_TRUE(gif_mapping);
|
|
||||||
|
|
||||||
ImageGeneratorRegistry registry;
|
|
||||||
std::shared_ptr<ImageGenerator> gif_generator =
|
|
||||||
registry.CreateCompatibleGenerator(gif_mapping);
|
|
||||||
ASSERT_TRUE(gif_generator);
|
|
||||||
|
|
||||||
TaskRunners runners(GetCurrentTestName(), // label
|
|
||||||
CreateNewThread("platform"), // platform
|
|
||||||
CreateNewThread("raster"), // raster
|
|
||||||
CreateNewThread("ui"), // ui
|
|
||||||
CreateNewThread("io") // io
|
|
||||||
);
|
|
||||||
|
|
||||||
std::unique_ptr<TestIOManager> io_manager;
|
|
||||||
fml::RefPtr<MultiFrameCodec> codec;
|
|
||||||
fml::AutoResetWaitableEvent latch;
|
|
||||||
|
|
||||||
auto validate_frame_callback = [&latch](Dart_NativeArguments args) {
|
|
||||||
EXPECT_FALSE(Dart_IsNull(Dart_GetNativeArgument(args, 0)));
|
|
||||||
latch.Signal();
|
|
||||||
};
|
|
||||||
|
|
||||||
AddNativeCallback("ValidateFrameCallback",
|
|
||||||
CREATE_NATIVE_ENTRY(validate_frame_callback));
|
|
||||||
|
|
||||||
// Setup the IO manager.
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() {
|
|
||||||
io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
|
|
||||||
// Mark GPU disabled.
|
|
||||||
io_manager->SetGpuDisabled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto isolate = RunDartCodeInIsolate(vm_ref, settings, runners, "main", {},
|
|
||||||
GetDefaultKernelFilePath(),
|
|
||||||
io_manager->GetWeakIOManager());
|
|
||||||
|
|
||||||
PostTaskSync(runners.GetUITaskRunner(), [&]() {
|
|
||||||
fml::AutoResetWaitableEvent isolate_latch;
|
|
||||||
|
|
||||||
EXPECT_TRUE(isolate->RunInIsolateScope([&]() -> bool {
|
|
||||||
Dart_Handle library = Dart_RootLibrary();
|
|
||||||
if (Dart_IsError(library)) {
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Dart_Handle closure =
|
|
||||||
Dart_GetField(library, Dart_NewStringFromCString("frameCallback"));
|
|
||||||
if (Dart_IsError(closure) || !Dart_IsClosure(closure)) {
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_FALSE(io_manager->did_access_is_gpu_disabled_sync_switch_);
|
|
||||||
codec = fml::MakeRefCounted<MultiFrameCodec>(std::move(gif_generator));
|
|
||||||
codec->getNextFrame(closure);
|
|
||||||
isolate_latch.Signal();
|
|
||||||
return true;
|
|
||||||
}));
|
|
||||||
isolate_latch.Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() {
|
|
||||||
EXPECT_TRUE(io_manager->did_access_is_gpu_disabled_sync_switch_);
|
|
||||||
});
|
|
||||||
|
|
||||||
latch.Wait();
|
|
||||||
|
|
||||||
// Destroy the Isolate
|
|
||||||
isolate = nullptr;
|
|
||||||
|
|
||||||
// Destroy the MultiFrameCodec
|
|
||||||
PostTaskSync(runners.GetUITaskRunner(), [&]() { codec = nullptr; });
|
|
||||||
|
|
||||||
// Destroy the IO manager
|
|
||||||
PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ImageDecoderFixtureTest, NullCheckBuffer) {
|
TEST_F(ImageDecoderFixtureTest, NullCheckBuffer) {
|
||||||
auto context = std::make_shared<impeller::TestImpellerContext>();
|
auto context = std::make_shared<impeller::TestImpellerContext>();
|
||||||
auto allocator = ImpellerAllocator(context->GetResourceAllocator());
|
auto allocator = ImpellerAllocator(context->GetResourceAllocator());
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "display_list/image/dl_image.h"
|
||||||
#include "flutter/fml/make_copyable.h"
|
#include "flutter/fml/make_copyable.h"
|
||||||
#include "flutter/lib/ui/painting/display_list_image_gpu.h"
|
#include "flutter/lib/ui/painting/display_list_image_gpu.h"
|
||||||
#include "flutter/lib/ui/painting/image.h"
|
#include "flutter/lib/ui/painting/image.h"
|
||||||
#if IMPELLER_SUPPORTS_RENDERING
|
#if IMPELLER_SUPPORTS_RENDERING
|
||||||
|
#include "flutter/impeller/renderer/context.h"
|
||||||
#include "flutter/lib/ui/painting/image_decoder_impeller.h"
|
#include "flutter/lib/ui/painting/image_decoder_impeller.h"
|
||||||
#endif // IMPELLER_SUPPORTS_RENDERING
|
#endif // IMPELLER_SUPPORTS_RENDERING
|
||||||
#include "third_party/dart/runtime/include/dart_api.h"
|
#include "third_party/dart/runtime/include/dart_api.h"
|
||||||
@ -144,10 +146,36 @@ MultiFrameCodec::State::GetNextFrameImage(
|
|||||||
|
|
||||||
#if IMPELLER_SUPPORTS_RENDERING
|
#if IMPELLER_SUPPORTS_RENDERING
|
||||||
if (is_impeller_enabled_) {
|
if (is_impeller_enabled_) {
|
||||||
|
#ifdef FML_OS_IOS
|
||||||
// This is safe regardless of whether the GPU is available or not because
|
// This is safe regardless of whether the GPU is available or not because
|
||||||
// without mipmap creation there is no command buffer encoding done.
|
// without mipmap creation there is no command buffer encoding done.
|
||||||
return ImageDecoderImpeller::UploadTextureToStorage(
|
return ImageDecoderImpeller::UploadTextureToStorage(
|
||||||
impeller_context, std::make_shared<SkBitmap>(bitmap));
|
impeller_context, std::make_shared<SkBitmap>(bitmap));
|
||||||
|
#else
|
||||||
|
sk_sp<DlImage> dl_image;
|
||||||
|
std::string error_message;
|
||||||
|
auto mapping = std::make_unique<fml::NonOwnedMapping>(
|
||||||
|
reinterpret_cast<const uint8_t*>(bitmap.getAddr(0, 0)), // data
|
||||||
|
bitmap.dimensions().area() * info.bytesPerPixel(), // size
|
||||||
|
[bitmap](auto, auto) mutable { bitmap.reset(); } // proc
|
||||||
|
);
|
||||||
|
std::shared_ptr<impeller::DeviceBuffer> device_buffer =
|
||||||
|
impeller_context->GetResourceAllocator()->CreateBufferWithCopy(
|
||||||
|
*mapping);
|
||||||
|
if (!device_buffer) {
|
||||||
|
return std::make_pair(nullptr, "Failed to allocate staging buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageDecoderImpeller::UploadTextureToPrivate(
|
||||||
|
[&](sk_sp<DlImage> image, std::string message) {
|
||||||
|
dl_image = std::move(image);
|
||||||
|
error_message = std::move(message);
|
||||||
|
},
|
||||||
|
impeller_context, device_buffer, info,
|
||||||
|
std::make_shared<SkBitmap>(bitmap), std::nullopt,
|
||||||
|
gpu_disable_sync_switch);
|
||||||
|
return std::make_pair(dl_image, error_message);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif // IMPELLER_SUPPORTS_RENDERING
|
#endif // IMPELLER_SUPPORTS_RENDERING
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user