Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: content/common/gpu/image_transport_surface_overlay_mac.mm

Issue 1280033004: Revert of Mac Overlays: Add GPU back-pressure (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/image_transport_surface_overlay_mac.mm
diff --git a/content/common/gpu/image_transport_surface_overlay_mac.mm b/content/common/gpu/image_transport_surface_overlay_mac.mm
index 213f0455b5e88763ff9a0438845403f4f2b9b9e9..1a528333529330c9b8872a8f6c71be59970c170b 100644
--- a/content/common/gpu/image_transport_surface_overlay_mac.mm
+++ b/content/common/gpu/image_transport_surface_overlay_mac.mm
@@ -4,92 +4,27 @@
#include "content/common/gpu/image_transport_surface_overlay_mac.h"
-#include <IOSurface/IOSurface.h>
-#include <OpenGL/GL.h>
+#include <OpenGL/gl.h>
-// This type consistently causes problem on Mac, and needs to be dealt with
-// in a systemic way.
-// http://crbug.com/517208
-#ifndef GL_OES_EGL_image
-typedef void* GLeglImageOES;
-#endif
-
-#include "base/mac/scoped_cftyperef.h"
#include "content/common/gpu/gpu_messages.h"
#include "ui/accelerated_widget_mac/surface_handle_types.h"
#include "ui/base/cocoa/animation_utils.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/gfx/geometry/dip_util.h"
-#include "ui/gl/gl_fence_apple.h"
#include "ui/gl/gl_image_io_surface.h"
-#include "ui/gl/scoped_api.h"
-#include "ui/gl/scoped_cgl.h"
-
-namespace {
-
-// Don't let a frame draw until 5% of the way through the next vsync interval
-// after the call to SwapBuffers. This slight offset is to ensure that skew
-// doesn't result in the frame being presented to the previous vsync interval.
-
-const double kVSyncIntervalFractionForEarliestDisplay = 0.05;
-// Target 50% of the way through the next vsync interval. Empirically, it has
-// been determined to be a good target for smooth animation.
-const double kVSyncIntervalFractionForDisplayCallback = 0.5;
-
-// If a frame takes more than 1/4th of a second for its fence to finish, just
-// pretend that the frame is ready to draw.
-const double kMaximumDelayWaitingForFenceInSeconds = 0.25;
-
-void CheckGLErrors(const char* msg) {
- GLenum gl_error;
- while ((gl_error = glGetError()) != GL_NO_ERROR) {
- LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error;
- }
-}
-
-} // namespace
-
-@interface CALayer(Private)
--(void)setContentsChanged;
-@end
namespace content {
-
-class ImageTransportSurfaceOverlayMac::PendingSwap {
- public:
- PendingSwap() : scale_factor(1) {}
- ~PendingSwap() { DCHECK(!fence); }
-
- gfx::Size pixel_size;
- float scale_factor;
- std::vector<ui::LatencyInfo> latency_info;
-
- // The IOSurface with new content for this swap.
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
-
- // A fence object, and the CGL context it was issued in.
- base::ScopedTypeRef<CGLContextObj> cgl_context;
- scoped_ptr<gfx::GLFenceAPPLE> fence;
-
- // The earliest time that this frame may be drawn. A frame is not allowed
- // to draw until a fraction of the way through the vsync interval after its
- // This extra latency is to allow wiggle-room for smoothness.
- base::TimeTicks earliest_allowed_draw_time;
- // After this time, always draw the frame, no matter what its fence says. This
- // is to prevent GL bugs from locking the compositor forever.
- base::TimeTicks latest_allowed_draw_time;
-};
ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
gfx::PluginWindowHandle handle)
- : scale_factor_(1), pending_overlay_image_(nullptr),
- has_pending_callback_(false), weak_factory_(this) {
+ : scale_factor_(1), pending_overlay_image_(nullptr) {
helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
}
ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() {
+ gfx::GLImageIOSurface::SetLayerForWidget(widget_, nil);
}
bool ImageTransportSurfaceOverlayMac::Initialize() {
@@ -102,225 +37,61 @@
ca_context_.reset(
[[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
layer_.reset([[CALayer alloc] init]);
- [layer_ setGeometryFlipped:YES];
- [layer_ setOpaque:YES];
[ca_context_ setLayer:layer_];
+
+ // Register the CALayer so that it can be picked up in GLImageIOSurface.
+ static intptr_t previous_widget = 0;
+ previous_widget += 1;
+ widget_ = reinterpret_cast<gfx::AcceleratedWidget>(previous_widget);
+ gfx::GLImageIOSurface::SetLayerForWidget(widget_, layer_);
+
return true;
}
-void ImageTransportSurfaceOverlayMac::Destroy() {
- FinishAllPendingSwaps();
-}
+void ImageTransportSurfaceOverlayMac::Destroy() {}
bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
return false;
}
-gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
- const gfx::Rect& pixel_damage_rect) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal");
+gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() {
+ TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffers");
- // Use the same concept of 'now' for the entire function. The duration of
- // this function only affect the result if this function lasts across a vsync
- // boundary, in which case smooth animation is out the window anyway.
- const base::TimeTicks now = base::TimeTicks::Now();
-
- // If the previous swap is ready to display, do it before flushing the
- // new swap. It is desirable to always be hitting this path when trying to
- // animate smoothly with vsync.
- if (!pending_swaps_.empty()) {
- if (IsFirstPendingSwapReadyToDisplay(now))
- DisplayFirstPendingSwapImmediately();
+ // A flush is required to ensure that all content appears in the layer.
+ {
+ TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFlush");
+ glFlush();
}
-
- // The remainder of the function will populate the PendingSwap structure and
- // then enqueue it.
- linked_ptr<PendingSwap> new_swap(new PendingSwap);
- new_swap->pixel_size = pixel_size_;
- new_swap->scale_factor = scale_factor_;
- new_swap->latency_info.swap(latency_info_);
// There should exist only one overlay image, and it should cover the whole
// surface.
DCHECK(pending_overlay_image_);
if (pending_overlay_image_) {
- gfx::GLImageIOSurface* pending_overlay_image_io_surface =
- static_cast<gfx::GLImageIOSurface*>(pending_overlay_image_);
- new_swap->io_surface = pending_overlay_image_io_surface->io_surface();
+ TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::setContents");
+ ScopedCAActionDisabler disabler;
+ gfx::Rect dip_bounds = gfx::ConvertRectToDIP(
+ scale_factor_, gfx::Rect(pixel_size_));
+ gfx::RectF crop_rect(0, 0, 1, 1);
+ pending_overlay_image_->ScheduleOverlayPlane(
+ widget_, 0, gfx::OVERLAY_TRANSFORM_NONE, dip_bounds, crop_rect);
pending_overlay_image_ = nullptr;
}
- // A flush is required to ensure that all content appears in the layer.
- {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::glFlush", "surface",
- new_swap->io_surface.get());
- CheckGLErrors("before flushing frame");
- new_swap->cgl_context.reset(CGLGetCurrentContext(),
- base::scoped_policy::RETAIN);
- new_swap->fence.reset(new gfx::GLFenceAPPLE);
- CheckGLErrors("while flushing frame");
- }
-
- // Compute the deadlines for drawing this frame.
- if (display_link_mac_) {
- new_swap->earliest_allowed_draw_time =
- display_link_mac_->GetNextVSyncTimeAfter(
- now, kVSyncIntervalFractionForEarliestDisplay);
- new_swap->latest_allowed_draw_time = now +
- base::TimeDelta::FromSecondsD(kMaximumDelayWaitingForFenceInSeconds);
- } else {
- // If we have no display link (because vsync is disabled or because we have
- // not received display parameters yet), immediately attempt to display the
- // surface.
- new_swap->earliest_allowed_draw_time = now;
- new_swap->latest_allowed_draw_time = now;
- }
-
- pending_swaps_.push_back(new_swap);
- PostCheckPendingSwapsCallbackIfNeeded(now);
- return gfx::SwapResult::SWAP_ACK;
-}
-
-bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay(
- const base::TimeTicks& now) {
- DCHECK(!pending_swaps_.empty());
- linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
- // If more that a certain amount of time has passed since the swap,
- // unconditionally continue.
- if (now > swap->latest_allowed_draw_time)
- return true;
-
- // Frames are disallowed from drawing until the vsync interval after their
- // swap is issued.
- if (now < swap->earliest_allowed_draw_time)
- return false;
-
- // If there is no fence then this is either for immediate display, or the
- // fence was aready successfully checked and deleted.
- if (!swap->fence)
- return true;
-
- // Check if the pending work has finished (and early-out if it is not, and
- // this is not forced).
- bool has_completed = false;
- {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
- CheckGLErrors("before testing fence");
- has_completed= swap->fence->HasCompleted();
- CheckGLErrors("after testing fence");
- if (has_completed) {
- swap->fence.reset();
- CheckGLErrors("while deleting fence");
- }
- }
- return has_completed;
-}
-
-void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately");
- DCHECK(!pending_swaps_.empty());
- linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
- // If there is a fence for this object, delete it.
- if (swap->fence) {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
- CheckGLErrors("before deleting active fence");
- swap->fence.reset();
- CheckGLErrors("while deleting active fence");
- }
-
- // Update the CALayer hierarchy.
- {
- TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents",
- "surface", swap->io_surface.get());
- ScopedCAActionDisabler disabler;
-
- id new_contents = static_cast<id>(swap->io_surface.get());
- [layer_ setContents:new_contents];
-
- CGRect new_frame = gfx::ConvertRectToDIP(
- swap->scale_factor, gfx::Rect(swap->pixel_size)).ToCGRect();
- if (!CGRectEqualToRect([layer_ frame], new_frame))
- [layer_ setFrame:new_frame];
- }
-
- // Send acknowledgement to the browser.
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
params.surface_handle =
ui::SurfaceHandleFromCAContextID([ca_context_ contextId]);
params.size = pixel_size_;
params.scale_factor = scale_factor_;
- params.latency_info.swap(swap->latency_info);
+ params.latency_info.swap(latency_info_);
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
-
- // Remove this from the queue, and reset any callback timers.
- pending_swaps_.pop_front();
-}
-
-void ImageTransportSurfaceOverlayMac::FinishAllPendingSwaps() {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::FinishAllPendingSwaps");
- while (!pending_swaps_.empty())
- DisplayFirstPendingSwapImmediately();
-}
-
-void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback");
-
- DCHECK(has_pending_callback_);
- has_pending_callback_ = false;
-
- if (pending_swaps_.empty())
- return;
-
- const base::TimeTicks now = base::TimeTicks::Now();
- if (IsFirstPendingSwapReadyToDisplay(now))
- DisplayFirstPendingSwapImmediately();
- PostCheckPendingSwapsCallbackIfNeeded(now);
-}
-
-void ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded(
- const base::TimeTicks& now) {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded");
-
- if (has_pending_callback_)
- return;
- if (pending_swaps_.empty())
- return;
-
- base::TimeTicks target;
- if (display_link_mac_) {
- target = display_link_mac_->GetNextVSyncTimeAfter(
- now, kVSyncIntervalFractionForDisplayCallback);
- } else {
- target = now;
- }
- base::TimeDelta delay = target - now;
-
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback,
- weak_factory_.GetWeakPtr()), delay);
- has_pending_callback_ = true;
-}
-
-gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() {
- return SwapBuffersInternal(gfx::Rect(pixel_size_));
+ return gfx::SwapResult::SWAP_ACK;
}
gfx::SwapResult ImageTransportSurfaceOverlayMac::PostSubBuffer(int x,
int y,
int width,
int height) {
- return SwapBuffersInternal(gfx::Rect(x, y, width, height));
+ return SwapBuffers();
}
bool ImageTransportSurfaceOverlayMac::SupportsPostSubBuffer() {
@@ -358,18 +129,10 @@
}
void ImageTransportSurfaceOverlayMac::OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
- if (display_link_mac_ &&
- display_link_mac_->display_id() == params.display_id_for_vsync)
- return;
- display_link_mac_ = ui::DisplayLinkMac::GetForDisplay(
- params.display_id_for_vsync);
-}
+ const AcceleratedSurfaceMsg_BufferPresented_Params& params) {}
void ImageTransportSurfaceOverlayMac::OnResize(gfx::Size pixel_size,
float scale_factor) {
- // Flush through any pending frames.
- FinishAllPendingSwaps();
pixel_size_ = pixel_size;
scale_factor_ = scale_factor;
}
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | gpu/command_buffer/service/gl_context_virtual.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698