blob: 824b2265d708e6508151f695768e57e074a1ec09 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/renderer_host/render_widget_helper.h"
#import <Cocoa/Cocoa.h>
#include <IOSurface/IOSurfaceAPI.h>
#include "base/bind.h"
#include "content/browser/compositor/browser_compositor_view_mac.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/common/gpu/gpu_messages.h"
namespace {
void OnNativeSurfaceBuffersSwappedOnUIThread(
base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
gfx::AcceleratedWidget native_widget =
content::GpuSurfaceTracker::Get()->AcquireNativeWidget(params.surface_id);
IOSurfaceID io_surface_handle = static_cast<IOSurfaceID>(
params.surface_handle);
[native_widget gotAcceleratedIOSurfaceFrame:io_surface_handle
withOutputSurfaceID:params.surface_id
withPixelSize:params.size
withScaleFactor:params.scale_factor];
}
} // namespace
namespace content {
void RenderWidgetHelper::OnNativeSurfaceBuffersSwappedOnIOThread(
GpuProcessHost* gpu_process_host,
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Immediately acknowledge this frame on the IO thread instead of the UI
// thread. The UI thread will wait on the GPU process. If the UI thread
// were to be responsible for acking swaps, then there would be a cycle
// and a potential deadlock.
// TODO(ccameron): This immediate ack circumvents GPU back-pressure that
// is necessary to throttle renderers. Fix that.
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.sync_point = 0;
ack_params.renderer_id = 0;
gpu_process_host->Send(new AcceleratedSurfaceMsg_BufferPresented(
params.route_id, ack_params));
// Open the IOSurface handle before returning, to ensure that it is not
// closed as soon as the frame is acknowledged.
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceLookup(
static_cast<uint32>(params.surface_handle)));
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&OnNativeSurfaceBuffersSwappedOnUIThread, io_surface, params));
}
} // namespace content