Commit 5d18e8de authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

SkaOutputSurfaceImpl: add EnqueueGpuTask() and FlushGpuTasks() methods.

SkaOutputSurfaceImpl defers draw until SwapBuffers. However SKiaRenderer
may issue other GPU tasks between Draw and SwapBuffers for example:
ScheduleOveralys(), ScheduleOutputSurfaceAsOverlay(), etc. Those tasks
will be executed before drawing task. It may causes problems.
Fix the issue by en-queuing all GPU tasks, and then defer and execute
them in order.

Bug: 1139697
Change-Id: I3e29fe6f60efd3f393b2bcc3ac4d536a305838f3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2482882
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarJonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818519}
parent 128845e6
......@@ -26,10 +26,6 @@
#include "third_party/skia/include/core/SkSurfaceCharacterization.h"
#include "third_party/skia/include/core/SkYUVAIndex.h"
namespace base {
class WaitableEvent;
}
namespace viz {
class ImageContextImpl;
......@@ -164,7 +160,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
private:
bool Initialize();
void InitializeOnGpuThread(GpuVSyncCallback vsync_callback_runner,
base::WaitableEvent* event,
bool* result);
SkSurfaceCharacterization CreateSkSurfaceCharacterization(
const gfx::Size& surface_size,
......@@ -179,8 +174,12 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
// Provided as a callback for the GPU thread.
void OnGpuVSync(base::TimeTicks timebase, base::TimeDelta interval);
void ScheduleGpuTask(base::OnceClosure callback,
std::vector<gpu::SyncToken> sync_tokens);
using GpuTask = base::OnceClosure;
void EnqueueGpuTask(GpuTask task,
std::vector<gpu::SyncToken> sync_tokens,
bool make_current,
bool need_framebuffer);
void FlushGpuTasks(bool wait_for_finish);
GrBackendFormat GetGrBackendFormatForTexture(
ResourceFormat resource_format,
uint32_t gl_texture_target,
......@@ -292,9 +291,14 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
bool should_measure_next_post_task_ = false;
// We defer the draw to the framebuffer until SwapBuffers or CopyOutput
// to avoid the expense of posting a task and calling MakeCurrent.
base::OnceCallback<bool()> deferred_framebuffer_draw_closure_;
// GPU tasks pending for flush.
std::vector<GpuTask> gpu_tasks_;
// GPU sync tokens which are depended by |gpu_tasks_|.
std::vector<gpu::SyncToken> gpu_task_sync_tokens_;
// True if _any_ of |gpu_tasks_| need a GL context.
bool make_current_ = false;
// True if _any_ of |gpu_tasks_| need to access the framebuffer.
bool need_framebuffer_ = false;
bool use_damage_area_from_skia_output_device_ = false;
// Damage area of the current buffer. Differ to the last submit buffer.
......
......@@ -119,7 +119,7 @@ class SkiaOutputSurfaceImplOnGpu
gfx::BufferFormat format,
bool use_stencil,
gfx::OverlayTransform transform);
bool FinishPaintCurrentFrame(sk_sp<SkDeferredDisplayList> ddl,
void FinishPaintCurrentFrame(sk_sp<SkDeferredDisplayList> ddl,
sk_sp<SkDeferredDisplayList> overdraw_ddl,
std::vector<ImageContextImpl*> image_contexts,
std::vector<gpu::SyncToken> sync_tokens,
......@@ -129,14 +129,11 @@ class SkiaOutputSurfaceImplOnGpu
void ScheduleOutputSurfaceAsOverlay(
const OverlayProcessorInterface::OutputSurfaceOverlayPlane&
output_surface_plane);
void SwapBuffers(
base::TimeTicks post_task_timestamp,
OutputSurfaceFrame frame,
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
void SwapBuffers(base::TimeTicks post_task_timestamp,
OutputSurfaceFrame frame);
// Runs |deferred_framebuffer_draw_closure| when SwapBuffers() or CopyOutput()
// will not.
void SwapBuffersSkipped(
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
void SwapBuffersSkipped();
void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); }
void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); }
void FinishPaintRenderPass(base::TimeTicks post_task_timestamp,
......@@ -150,11 +147,10 @@ class SkiaOutputSurfaceImplOnGpu
void RemoveRenderPassResource(
std::vector<AggregatedRenderPassId> ids,
std::vector<std::unique_ptr<ImageContextImpl>> image_contexts);
bool CopyOutput(AggregatedRenderPassId id,
void CopyOutput(AggregatedRenderPassId id,
copy_output::RenderPassGeometry geometry,
const gfx::ColorSpace& color_space,
std::unique_ptr<CopyOutputRequest> request,
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
std::unique_ptr<CopyOutputRequest> request);
void BeginAccessImages(const std::vector<ImageContextImpl*>& image_contexts,
std::vector<GrBackendSemaphore>* begin_semaphores,
......@@ -209,6 +205,10 @@ class SkiaOutputSurfaceImplOnGpu
gpu::MemoryTracker* GetMemoryTracker() { return memory_tracker_; }
// Make context current for GL, and return false if the context is lost.
// It will do nothing when Vulkan is used.
bool MakeCurrent(bool need_framebuffer);
private:
class OffscreenSurface;
class DisplayContext;
......@@ -224,9 +224,6 @@ class SkiaOutputSurfaceImplOnGpu
DidSwapBufferCompleteCallback GetDidSwapBuffersCompleteCallback();
// Make context current for GL, and return false if the context is lost.
// It will do nothing when Vulkan is used.
bool MakeCurrent(bool need_fbo0);
void MarkContextLost(ContextLostReason reason);
void DestroySharedImageOnImplThread(
......@@ -239,9 +236,7 @@ class SkiaOutputSurfaceImplOnGpu
void ReleaseFenceSyncAndPushTextureUpdates(uint64_t sync_fence_release);
void SwapBuffersInternal(
base::OnceCallback<bool()> deferred_framebuffer_draw_closure,
OutputSurfaceFrame* frame = nullptr);
void SwapBuffersInternal(OutputSurfaceFrame* frame = nullptr);
GrDirectContext* gr_context() { return context_state_->gr_context(); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment