#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h"
#include "base/location.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_skia.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace blink {
namespace {
constexpr base::TimeDelta kCreateBlobSlackBeforeDeadline = …;
constexpr base::TimeDelta kEncodeRowSlackBeforeDeadline = …;
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_WIN))
const double kIdleTaskStartTimeoutDelayMs = …;
#else
const double kIdleTaskStartTimeoutDelayMs = 4000.0;
#endif
#if !BUILDFLAG(IS_ANDROID)
const double kIdleTaskCompleteTimeoutDelayMs = …;
#else
const double kIdleTaskCompleteTimeoutDelayMs = 9000.0;
#endif
bool IsCreateBlobDeadlineNearOrPassed(base::TimeTicks deadline) { … }
bool IsEncodeRowDeadlineNearOrPassed(base::TimeTicks deadline,
size_t image_width) { … }
void RecordIdleTaskStatusHistogram(
CanvasAsyncBlobCreator::IdleTaskStatus status) { … }
void RecordInitiateEncodingTimeHistogram(ImageEncodingMimeType mime_type,
base::TimeDelta elapsed_time) { … }
void RecordCompleteEncodingTimeHistogram(ImageEncodingMimeType mime_type,
base::TimeDelta elapsed_time) { … }
void RecordScaledDurationHistogram(ImageEncodingMimeType mime_type,
base::TimeDelta elapsed_time,
float width,
float height) { … }
}
CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
scoped_refptr<StaticBitmapImage> image,
const ImageEncodeOptions* options,
ToBlobFunctionType function_type,
base::TimeTicks start_time,
ExecutionContext* context,
const IdentifiableToken& input_digest,
ScriptPromiseResolver<Blob>* resolver)
: … { … }
CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
scoped_refptr<StaticBitmapImage> image,
const ImageEncodeOptions* options,
ToBlobFunctionType function_type,
V8BlobCallback* callback,
base::TimeTicks start_time,
ExecutionContext* context,
const IdentifiableToken& input_digest,
ScriptPromiseResolver<Blob>* resolver)
: … { … }
CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() = default;
void CanvasAsyncBlobCreator::Dispose() { … }
ImageEncodeOptions* CanvasAsyncBlobCreator::GetImageEncodeOptionsForMimeType(
ImageEncodingMimeType mime_type) { … }
bool CanvasAsyncBlobCreator::EncodeImage(
std::unique_ptr<ImageDataBuffer> buffer,
ImageEncodingMimeType mime_type,
const double& quality,
Vector<unsigned char>* encoded_image) { … }
void CanvasAsyncBlobCreator::ScheduleAsyncBlobCreation(const double& quality) { … }
void CanvasAsyncBlobCreator::ScheduleInitiateEncoding(double quality) { … }
void CanvasAsyncBlobCreator::InitiateEncoding(double quality,
base::TimeTicks deadline) { … }
void CanvasAsyncBlobCreator::IdleEncodeRows(base::TimeTicks deadline) { … }
void CanvasAsyncBlobCreator::ForceEncodeRows() { … }
void CanvasAsyncBlobCreator::CreateBlobAndReturnResult(
Vector<unsigned char> encoded_image) { … }
void CanvasAsyncBlobCreator::RecordIdentifiabilityMetric() { … }
void CanvasAsyncBlobCreator::TraceCanvasContent(
Vector<unsigned char>* encoded_image) { … }
void CanvasAsyncBlobCreator::CreateNullAndReturnResult() { … }
void CanvasAsyncBlobCreator::EncodeImageOnEncoderThread(
CrossThreadHandle<CanvasAsyncBlobCreator> cross_thread_handle,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
sk_sp<SkImage> skia_image,
std::unique_ptr<ImageDataBuffer> data_buffer,
ImageEncodingMimeType mime_type,
double quality) { … }
bool CanvasAsyncBlobCreator::InitializeEncoder(double quality) { … }
void CanvasAsyncBlobCreator::IdleTaskStartTimeoutEvent(double quality) { … }
void CanvasAsyncBlobCreator::IdleTaskCompleteTimeoutEvent() { … }
void CanvasAsyncBlobCreator::PostDelayedTaskToCurrentThread(
const base::Location& location,
base::OnceClosure task,
double delay_ms) { … }
void CanvasAsyncBlobCreator::Trace(Visitor* visitor) const { … }
}