[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 std::shared_ptr<SkBitmap>& bitmap,
|
||||
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__);
|
||||
if (!context) {
|
||||
result(nullptr, "No Impeller context is available");
|
||||
|
@ -88,7 +88,7 @@ class ImageDecoderImpeller final : public ImageDecoder {
|
||||
const SkImageInfo& image_info,
|
||||
const std::shared_ptr<SkBitmap>& bitmap,
|
||||
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.
|
||||
/// @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(result.second, "");
|
||||
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);
|
||||
}
|
||||
@ -1007,174 +1010,6 @@ TEST_F(ImageDecoderFixtureTest,
|
||||
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) {
|
||||
auto context = std::make_shared<impeller::TestImpellerContext>();
|
||||
auto allocator = ImpellerAllocator(context->GetResourceAllocator());
|
||||
|
@ -6,10 +6,12 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "display_list/image/dl_image.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/lib/ui/painting/display_list_image_gpu.h"
|
||||
#include "flutter/lib/ui/painting/image.h"
|
||||
#if IMPELLER_SUPPORTS_RENDERING
|
||||
#include "flutter/impeller/renderer/context.h"
|
||||
#include "flutter/lib/ui/painting/image_decoder_impeller.h"
|
||||
#endif // IMPELLER_SUPPORTS_RENDERING
|
||||
#include "third_party/dart/runtime/include/dart_api.h"
|
||||
@ -144,10 +146,36 @@ MultiFrameCodec::State::GetNextFrameImage(
|
||||
|
||||
#if IMPELLER_SUPPORTS_RENDERING
|
||||
if (is_impeller_enabled_) {
|
||||
#ifdef FML_OS_IOS
|
||||
// This is safe regardless of whether the GPU is available or not because
|
||||
// without mipmap creation there is no command buffer encoding done.
|
||||
return ImageDecoderImpeller::UploadTextureToStorage(
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user