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 @@ ...@@ -26,10 +26,6 @@
#include "third_party/skia/include/core/SkSurfaceCharacterization.h" #include "third_party/skia/include/core/SkSurfaceCharacterization.h"
#include "third_party/skia/include/core/SkYUVAIndex.h" #include "third_party/skia/include/core/SkYUVAIndex.h"
namespace base {
class WaitableEvent;
}
namespace viz { namespace viz {
class ImageContextImpl; class ImageContextImpl;
...@@ -164,7 +160,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -164,7 +160,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
private: private:
bool Initialize(); bool Initialize();
void InitializeOnGpuThread(GpuVSyncCallback vsync_callback_runner, void InitializeOnGpuThread(GpuVSyncCallback vsync_callback_runner,
base::WaitableEvent* event,
bool* result); bool* result);
SkSurfaceCharacterization CreateSkSurfaceCharacterization( SkSurfaceCharacterization CreateSkSurfaceCharacterization(
const gfx::Size& surface_size, const gfx::Size& surface_size,
...@@ -179,8 +174,12 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -179,8 +174,12 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
// Provided as a callback for the GPU thread. // Provided as a callback for the GPU thread.
void OnGpuVSync(base::TimeTicks timebase, base::TimeDelta interval); void OnGpuVSync(base::TimeTicks timebase, base::TimeDelta interval);
void ScheduleGpuTask(base::OnceClosure callback, using GpuTask = base::OnceClosure;
std::vector<gpu::SyncToken> sync_tokens); void EnqueueGpuTask(GpuTask task,
std::vector<gpu::SyncToken> sync_tokens,
bool make_current,
bool need_framebuffer);
void FlushGpuTasks(bool wait_for_finish);
GrBackendFormat GetGrBackendFormatForTexture( GrBackendFormat GetGrBackendFormatForTexture(
ResourceFormat resource_format, ResourceFormat resource_format,
uint32_t gl_texture_target, uint32_t gl_texture_target,
...@@ -292,9 +291,14 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -292,9 +291,14 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
bool should_measure_next_post_task_ = false; bool should_measure_next_post_task_ = false;
// We defer the draw to the framebuffer until SwapBuffers or CopyOutput // GPU tasks pending for flush.
// to avoid the expense of posting a task and calling MakeCurrent. std::vector<GpuTask> gpu_tasks_;
base::OnceCallback<bool()> deferred_framebuffer_draw_closure_; // 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; bool use_damage_area_from_skia_output_device_ = false;
// Damage area of the current buffer. Differ to the last submit buffer. // Damage area of the current buffer. Differ to the last submit buffer.
......
...@@ -119,7 +119,7 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -119,7 +119,7 @@ class SkiaOutputSurfaceImplOnGpu
gfx::BufferFormat format, gfx::BufferFormat format,
bool use_stencil, bool use_stencil,
gfx::OverlayTransform transform); gfx::OverlayTransform transform);
bool FinishPaintCurrentFrame(sk_sp<SkDeferredDisplayList> ddl, void FinishPaintCurrentFrame(sk_sp<SkDeferredDisplayList> ddl,
sk_sp<SkDeferredDisplayList> overdraw_ddl, sk_sp<SkDeferredDisplayList> overdraw_ddl,
std::vector<ImageContextImpl*> image_contexts, std::vector<ImageContextImpl*> image_contexts,
std::vector<gpu::SyncToken> sync_tokens, std::vector<gpu::SyncToken> sync_tokens,
...@@ -129,14 +129,11 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -129,14 +129,11 @@ class SkiaOutputSurfaceImplOnGpu
void ScheduleOutputSurfaceAsOverlay( void ScheduleOutputSurfaceAsOverlay(
const OverlayProcessorInterface::OutputSurfaceOverlayPlane& const OverlayProcessorInterface::OutputSurfaceOverlayPlane&
output_surface_plane); output_surface_plane);
void SwapBuffers( void SwapBuffers(base::TimeTicks post_task_timestamp,
base::TimeTicks post_task_timestamp, OutputSurfaceFrame frame);
OutputSurfaceFrame frame,
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
// Runs |deferred_framebuffer_draw_closure| when SwapBuffers() or CopyOutput() // Runs |deferred_framebuffer_draw_closure| when SwapBuffers() or CopyOutput()
// will not. // will not.
void SwapBuffersSkipped( void SwapBuffersSkipped();
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); } void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); }
void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); } void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); }
void FinishPaintRenderPass(base::TimeTicks post_task_timestamp, void FinishPaintRenderPass(base::TimeTicks post_task_timestamp,
...@@ -150,11 +147,10 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -150,11 +147,10 @@ class SkiaOutputSurfaceImplOnGpu
void RemoveRenderPassResource( void RemoveRenderPassResource(
std::vector<AggregatedRenderPassId> ids, std::vector<AggregatedRenderPassId> ids,
std::vector<std::unique_ptr<ImageContextImpl>> image_contexts); std::vector<std::unique_ptr<ImageContextImpl>> image_contexts);
bool CopyOutput(AggregatedRenderPassId id, void CopyOutput(AggregatedRenderPassId id,
copy_output::RenderPassGeometry geometry, copy_output::RenderPassGeometry geometry,
const gfx::ColorSpace& color_space, const gfx::ColorSpace& color_space,
std::unique_ptr<CopyOutputRequest> request, std::unique_ptr<CopyOutputRequest> request);
base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
void BeginAccessImages(const std::vector<ImageContextImpl*>& image_contexts, void BeginAccessImages(const std::vector<ImageContextImpl*>& image_contexts,
std::vector<GrBackendSemaphore>* begin_semaphores, std::vector<GrBackendSemaphore>* begin_semaphores,
...@@ -209,6 +205,10 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -209,6 +205,10 @@ class SkiaOutputSurfaceImplOnGpu
gpu::MemoryTracker* GetMemoryTracker() { return memory_tracker_; } 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: private:
class OffscreenSurface; class OffscreenSurface;
class DisplayContext; class DisplayContext;
...@@ -224,9 +224,6 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -224,9 +224,6 @@ class SkiaOutputSurfaceImplOnGpu
DidSwapBufferCompleteCallback GetDidSwapBuffersCompleteCallback(); 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 MarkContextLost(ContextLostReason reason);
void DestroySharedImageOnImplThread( void DestroySharedImageOnImplThread(
...@@ -239,9 +236,7 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -239,9 +236,7 @@ class SkiaOutputSurfaceImplOnGpu
void ReleaseFenceSyncAndPushTextureUpdates(uint64_t sync_fence_release); void ReleaseFenceSyncAndPushTextureUpdates(uint64_t sync_fence_release);
void SwapBuffersInternal( void SwapBuffersInternal(OutputSurfaceFrame* frame = nullptr);
base::OnceCallback<bool()> deferred_framebuffer_draw_closure,
OutputSurfaceFrame* frame = nullptr);
GrDirectContext* gr_context() { return context_state_->gr_context(); } 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