Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates in flutter/lib/ui for the shell refactor (Patch 7) #4835

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions lib/ui/BUILD.gn
Expand Up @@ -38,14 +38,10 @@ source_set("ui") {
"painting/picture.h",
"painting/picture_recorder.cc",
"painting/picture_recorder.h",
"painting/resource_context.cc",
"painting/resource_context.h",
"painting/rrect.cc",
"painting/rrect.h",
"painting/shader.cc",
"painting/shader.h",
"painting/utils.cc",
"painting/utils.h",
"painting/vertices.cc",
"painting/vertices.h",
"semantics/semantics_node.cc",
Expand Down Expand Up @@ -85,19 +81,18 @@ source_set("ui") {
"window/window.h",
]

public_configs = [
"$flutter_root:config",
]
public_configs = [ "$flutter_root:config" ]

deps = [
"//third_party/dart/runtime/bin:embedded_dart_io",
"$flutter_root/assets",
"$flutter_root/common",
"$flutter_root/flow",
"$flutter_root/fml",
"$flutter_root/glue",
"$flutter_root/runtime:test_font",
"$flutter_root/sky/engine",
"$flutter_root/third_party/txt",
"//third_party/dart/runtime/bin:embedded_dart_io",
"//third_party/rapidjson",
"//third_party/skia",
"//third_party/skia:gpu",
Expand Down
9 changes: 5 additions & 4 deletions lib/ui/compositing/scene_builder.cc
Expand Up @@ -120,10 +120,11 @@ void SceneBuilder::addPicture(double dx,
double dy,
Picture* picture,
int hints) {
layer_builder_->PushPicture(SkPoint::Make(dx, dy), //
picture->picture(), //
!!(hints & 1), // picture is complex
!!(hints & 2) // picture will change
layer_builder_->PushPicture(
SkPoint::Make(dx, dy), //
UIDartState::CreateGPUObject(picture->picture()), //
!!(hints & 1), // picture is complex
!!(hints & 2) // picture will change
);
}

Expand Down
6 changes: 4 additions & 2 deletions lib/ui/compositing/scene_host.cc
Expand Up @@ -4,6 +4,7 @@

#include "flutter/lib/ui/compositing/scene_host.h"

#include "flutter/lib/ui/ui_dart_state.h"
#include "lib/tonic/dart_args.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/dart_library_natives.h"
Expand Down Expand Up @@ -37,8 +38,9 @@ fxl::RefPtr<SceneHost> SceneHost::create(
}

SceneHost::SceneHost(fxl::RefPtr<zircon::dart::Handle> export_token_handle) {
export_node_holder_ =
fxl::MakeRefCounted<flow::ExportNodeHolder>(export_token_handle);
export_node_holder_ = fxl::MakeRefCounted<flow::ExportNodeHolder>(
blink::UIDartState::Current()->GetTaskRunners().GetGPUTaskRunner(),
export_token_handle);
}
#else
fxl::RefPtr<SceneHost> SceneHost::create(Dart_Handle export_token_handle) {
Expand Down
62 changes: 44 additions & 18 deletions lib/ui/dart_runtime_hooks.cc
Expand Up @@ -8,7 +8,11 @@
#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <sstream>

#include "flutter/common/settings.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "lib/fxl/build_config.h"
#include "lib/fxl/logging.h"
#include "lib/tonic/converter/dart_converter.h"
Expand Down Expand Up @@ -141,44 +145,66 @@ void DartRuntimeHooks::Install(IsolateType isolate_type,
// Implementation of native functions which are used for some
// test/debug functionality in standalone dart mode.
void Logger_PrintString(Dart_NativeArguments args) {
intptr_t length = 0;
uint8_t* chars = nullptr;
Dart_Handle str = Dart_GetNativeArgument(args, 0);
Dart_Handle result = Dart_StringToUTF8(str, &chars, &length);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
} else {
std::stringstream stream;
const auto& logger_prefix = UIDartState::Current()->logger_prefix();

#if !OS(ANDROID)
// Prepend all logs with the isolate debug name except on Android where that
// prefix is specified in the log tag.
if (logger_prefix.size() > 0) {
stream << logger_prefix << ": ";
}
#endif // !OS(ANDROID)

// Append the log buffer obtained from Dart code.
{
Dart_Handle str = Dart_GetNativeArgument(args, 0);
uint8_t* chars = nullptr;
intptr_t length = 0;
Dart_Handle result = Dart_StringToUTF8(str, &chars, &length);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
return;
}
if (length > 0) {
stream << std::string{reinterpret_cast<const char*>(chars),
static_cast<size_t>(length)};
}
}

const auto log_string = stream.str();
const char* chars = log_string.c_str();
const size_t length = log_string.size();

// Log using platform specific mechanisms
{
#if defined(OS_ANDROID)
// Write to the logcat on Android.
const char* tag = Settings::Get().log_tag.c_str();
__android_log_print(ANDROID_LOG_INFO, tag, "%.*s", (int)length, chars);
__android_log_print(ANDROID_LOG_INFO, logger_prefix.c_str(), "%.*s",
(int)length, chars);
#elif defined(OS_IOS)
// Write to syslog on iOS.
//
// TODO(cbracken): replace with dedicated communication channel and bypass
// iOS logging APIs altogether.
syslog(1 /* LOG_ALERT */, "%.*s", (int)length, chars);
#else
// On Fuchsia and in flutter_tester (on both macOS and Linux), write
// directly to stdout.
fwrite(chars, 1, length, stdout);
fputs("\n", stdout);
fflush(stdout);
std::cout << log_string << std::endl;
#endif
}

if (dart::bin::ShouldCaptureStdout()) {
// For now we report print output on the Stdout stream.
uint8_t newline[] = {'\n'};
Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
reinterpret_cast<const uint8_t*>(chars), length);
Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
}
}

void ScheduleMicrotask(Dart_NativeArguments args) {
Dart_Handle closure = Dart_GetNativeArgument(args, 0);
if (LogIfError(closure) || !Dart_IsClosure(closure))
return;
tonic::DartMicrotaskQueue::GetForCurrentThread()->ScheduleMicrotask(closure);
UIDartState::Current()->ScheduleMicrotask(closure);
}

} // namespace blink
109 changes: 65 additions & 44 deletions lib/ui/painting/codec.cc
Expand Up @@ -4,10 +4,9 @@

#include "flutter/lib/ui/painting/codec.h"

#include "flutter/common/threads.h"
#include "flutter/common/task_runners.h"
#include "flutter/glue/trace_event.h"
#include "flutter/lib/ui/painting/frame_info.h"
#include "flutter/lib/ui/painting/resource_context.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/dart_library_natives.h"
Expand All @@ -28,9 +27,9 @@ namespace {
static constexpr const char* kInitCodecTraceTag = "InitCodec";
static constexpr const char* kCodecNextFrameTraceTag = "CodecNextFrame";

void InvokeCodecCallback(fxl::RefPtr<Codec> codec,
std::unique_ptr<DartPersistentValue> callback,
size_t trace_id) {
static void InvokeCodecCallback(fxl::RefPtr<Codec> codec,
std::unique_ptr<DartPersistentValue> callback,
size_t trace_id) {
tonic::DartState* dart_state = callback->dart_state().get();
if (!dart_state) {
TRACE_FLOW_END("flutter", kInitCodecTraceTag, trace_id);
Expand All @@ -45,21 +44,21 @@ void InvokeCodecCallback(fxl::RefPtr<Codec> codec,
TRACE_FLOW_END("flutter", kInitCodecTraceTag, trace_id);
}

sk_sp<SkImage> DecodeImage(sk_sp<SkData> buffer, size_t trace_id) {
static sk_sp<SkImage> DecodeImage(fml::WeakPtr<GrContext> context,
sk_sp<SkData> buffer,
size_t trace_id) {
TRACE_FLOW_STEP("flutter", kInitCodecTraceTag, trace_id);
TRACE_EVENT0("flutter", "DecodeImage");

if (buffer == nullptr || buffer->isEmpty()) {
return nullptr;
}

std::unique_ptr<ResourceContext> resourceContext = ResourceContext::Acquire();
GrContext* context = resourceContext->Get();
if (context) {
// This indicates that we do not want a "linear blending" decode.
sk_sp<SkColorSpace> dstColorSpace = nullptr;
return SkImage::MakeCrossContextFromEncoded(context, std::move(buffer),
false, dstColorSpace.get());
return SkImage::MakeCrossContextFromEncoded(
context.get(), std::move(buffer), false, dstColorSpace.get());
} else {
// Defer decoding until time of draw later on the GPU thread. Can happen
// when GL operations are currently forbidden such as in the background
Expand All @@ -68,7 +67,10 @@ sk_sp<SkImage> DecodeImage(sk_sp<SkData> buffer, size_t trace_id) {
}
}

fxl::RefPtr<Codec> InitCodec(sk_sp<SkData> buffer, size_t trace_id) {
fxl::RefPtr<Codec> InitCodec(fml::WeakPtr<GrContext> context,
sk_sp<SkData> buffer,
fxl::RefPtr<flow::SkiaUnrefQueue> unref_queue,
size_t trace_id) {
TRACE_FLOW_STEP("flutter", kInitCodecTraceTag, trace_id);
TRACE_EVENT0("blink", "InitCodec");

Expand All @@ -86,27 +88,31 @@ fxl::RefPtr<Codec> InitCodec(sk_sp<SkData> buffer, size_t trace_id) {
if (skCodec->getFrameCount() > 1) {
return fxl::MakeRefCounted<MultiFrameCodec>(std::move(skCodec));
}
auto skImage = DecodeImage(buffer, trace_id);
auto skImage = DecodeImage(context, buffer, trace_id);
if (!skImage) {
FXL_LOG(ERROR) << "DecodeImage failed";
return nullptr;
}
auto image = CanvasImage::Create();
image->set_image(skImage);
image->set_image({skImage, unref_queue});
auto frameInfo = fxl::MakeRefCounted<FrameInfo>(std::move(image), 0);
return fxl::MakeRefCounted<SingleFrameCodec>(std::move(frameInfo));
}

void InitCodecAndInvokeCodecCallback(
fxl::RefPtr<fxl::TaskRunner> ui_task_runner,
fml::WeakPtr<GrContext> context,
fxl::RefPtr<flow::SkiaUnrefQueue> unref_queue,
std::unique_ptr<DartPersistentValue> callback,
sk_sp<SkData> buffer,
size_t trace_id) {
auto codec = InitCodec(std::move(buffer), trace_id);
Threads::UI()->PostTask(fxl::MakeCopyable([
callback = std::move(callback), codec = std::move(codec), trace_id
]() mutable {
InvokeCodecCallback(std::move(codec), std::move(callback), trace_id);
}));
auto codec =
InitCodec(context, std::move(buffer), std::move(unref_queue), trace_id);
ui_task_runner->PostTask(
fxl::MakeCopyable([callback = std::move(callback),
codec = std::move(codec), trace_id]() mutable {
InvokeCodecCallback(std::move(codec), std::move(callback), trace_id);
}));
}

void InstantiateImageCodec(Dart_NativeArguments args) {
Expand All @@ -133,14 +139,20 @@ void InstantiateImageCodec(Dart_NativeArguments args) {

auto buffer = SkData::MakeWithCopy(list.data(), list.num_elements());

Threads::IO()->PostTask(fxl::MakeCopyable([
callback = std::make_unique<DartPersistentValue>(
tonic::DartState::Current(), callback_handle),
buffer = std::move(buffer), trace_id
]() mutable {
InitCodecAndInvokeCodecCallback(std::move(callback), std::move(buffer),
trace_id);
}));
auto dart_state = UIDartState::Current();

const auto& task_runners = dart_state->GetTaskRunners();
task_runners.GetIOTaskRunner()->PostTask(fxl::MakeCopyable(
[callback = std::make_unique<DartPersistentValue>(
tonic::DartState::Current(), callback_handle),
buffer = std::move(buffer), trace_id,
ui_task_runner = task_runners.GetUITaskRunner(),
context = dart_state->GetResourceContext(),
queue = UIDartState::Current()->GetSkiaUnrefQueue()]() mutable {
InitCodecAndInvokeCodecCallback(std::move(ui_task_runner), context,
std::move(queue), std::move(callback),
std::move(buffer), trace_id);
}));
}

bool copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
Expand Down Expand Up @@ -213,7 +225,8 @@ MultiFrameCodec::MultiFrameCodec(std::unique_ptr<SkCodec> codec)
nextFrameIndex_ = 0;
}

sk_sp<SkImage> MultiFrameCodec::GetNextFrameImage() {
sk_sp<SkImage> MultiFrameCodec::GetNextFrameImage(
fml::WeakPtr<GrContext> resourceContext) {
SkBitmap& bitmap = frameBitmaps_[nextFrameIndex_];
if (!bitmap.getPixels()) { // We haven't decoded this frame yet
const SkImageInfo info = codec_->getInfo().makeColorType(kN32_SkColorType);
Expand Down Expand Up @@ -245,15 +258,13 @@ sk_sp<SkImage> MultiFrameCodec::GetNextFrameImage() {
}
}

std::unique_ptr<ResourceContext> resourceContext = ResourceContext::Acquire();
GrContext* context = resourceContext->Get();
if (context) {
if (resourceContext) {
SkPixmap pixmap(bitmap.info(), bitmap.pixelRef()->pixels(),
bitmap.pixelRef()->rowBytes());
// This indicates that we do not want a "linear blending" decode.
sk_sp<SkColorSpace> dstColorSpace = nullptr;
return SkImage::MakeCrossContextFromPixmap(context, pixmap, false,
dstColorSpace.get());
return SkImage::MakeCrossContextFromPixmap(resourceContext.get(), pixmap,
false, dstColorSpace.get());
} else {
// Defer decoding until time of draw later on the GPU thread. Can happen
// when GL operations are currently forbidden such as in the background
Expand All @@ -264,19 +275,22 @@ sk_sp<SkImage> MultiFrameCodec::GetNextFrameImage() {

void MultiFrameCodec::GetNextFrameAndInvokeCallback(
std::unique_ptr<DartPersistentValue> callback,
fxl::RefPtr<fxl::TaskRunner> ui_task_runner,
fml::WeakPtr<GrContext> resourceContext,
fxl::RefPtr<flow::SkiaUnrefQueue> unref_queue,
size_t trace_id) {
fxl::RefPtr<FrameInfo> frameInfo = NULL;
sk_sp<SkImage> skImage = GetNextFrameImage();
sk_sp<SkImage> skImage = GetNextFrameImage(resourceContext);
if (skImage) {
fxl::RefPtr<CanvasImage> image = CanvasImage::Create();
image->set_image(skImage);
image->set_image({skImage, std::move(unref_queue)});
frameInfo = fxl::MakeRefCounted<FrameInfo>(
std::move(image), frameInfos_[nextFrameIndex_].fDuration);
}
nextFrameIndex_ = (nextFrameIndex_ + 1) % frameInfos_.size();

Threads::UI()->PostTask(fxl::MakeCopyable(
[ callback = std::move(callback), frameInfo, trace_id ]() mutable {
ui_task_runner->PostTask(fxl::MakeCopyable(
[callback = std::move(callback), frameInfo, trace_id]() mutable {
InvokeNextFrameCallback(frameInfo, std::move(callback), trace_id);
}));

Expand All @@ -293,13 +307,20 @@ Dart_Handle MultiFrameCodec::getNextFrame(Dart_Handle callback_handle) {
return ToDart("Callback must be a function");
}

Threads::IO()->PostTask(fxl::MakeCopyable([
callback = std::make_unique<DartPersistentValue>(
tonic::DartState::Current(), callback_handle),
this, trace_id
]() mutable {
GetNextFrameAndInvokeCallback(std::move(callback), trace_id);
}));
auto dart_state = UIDartState::Current();

const auto& task_runners = dart_state->GetTaskRunners();

task_runners.GetIOTaskRunner()->PostTask(fxl::MakeCopyable(
[callback = std::make_unique<DartPersistentValue>(
tonic::DartState::Current(), callback_handle),
this, trace_id, ui_task_runner = task_runners.GetUITaskRunner(),
queue = UIDartState::Current()->GetSkiaUnrefQueue(),
context = dart_state->GetResourceContext()]() mutable {
GetNextFrameAndInvokeCallback(std::move(callback),
std::move(ui_task_runner), context,
std::move(queue), trace_id);
}));

return Dart_Null();
}
Expand Down