summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/gpu_scheduler_mac.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service/gpu_scheduler_mac.cc')
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_mac.cc142
1 files changed, 142 insertions, 0 deletions
diff --git a/gpu/command_buffer/service/gpu_scheduler_mac.cc b/gpu/command_buffer/service/gpu_scheduler_mac.cc
new file mode 100644
index 0000000..f89bfb5
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_scheduler_mac.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2011 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 "gpu/command_buffer/service/gpu_scheduler.h"
+#include "ui/gfx/gl/gl_context.h"
+
+using ::base::SharedMemory;
+
+namespace gpu {
+
+bool GpuScheduler::Initialize(
+ gfx::PluginWindowHandle window,
+ const gfx::Size& size,
+ const gles2::DisallowedExtensions& disallowed_extensions,
+ const char* allowed_extensions,
+ const std::vector<int32>& attribs,
+ GpuScheduler* parent,
+ uint32 parent_texture_id) {
+ // Get the parent decoder and the GLContext to share IDs with, if any.
+ gles2::GLES2Decoder* parent_decoder = NULL;
+ gfx::GLContext* parent_context = NULL;
+ if (parent) {
+ parent_decoder = parent->decoder_.get();
+ DCHECK(parent_decoder);
+
+ parent_context = parent_decoder->GetGLContext();
+ DCHECK(parent_context);
+ }
+
+ scoped_ptr<gfx::GLContext> context(
+ gfx::GLContext::CreateOffscreenGLContext(parent_context));
+ if (!context.get())
+ return false;
+
+ // On Mac OS X since we can not render on-screen we don't even
+ // attempt to create a view based GLContext. The only difference
+ // between "on-screen" and "off-screen" rendering on this platform
+ // is whether we allocate an AcceleratedSurface, which transmits the
+ // rendering results back to the browser.
+ if (window) {
+ surface_.reset(new AcceleratedSurface());
+
+ // Note that although the GLContext is passed to Initialize and the
+ // GLContext will later be owned by the decoder, AcceleratedSurface does
+ // not hold on to the reference. It simply extracts the underlying GL
+ // context in order to share the namespace with another context.
+ if (!surface_->Initialize(context.get(), false)) {
+ LOG(ERROR) << "GpuScheduler::Initialize failed to "
+ << "initialize AcceleratedSurface.";
+ Destroy();
+ return false;
+ }
+ }
+
+ return InitializeCommon(context.release(),
+ size,
+ disallowed_extensions,
+ allowed_extensions,
+ attribs,
+ parent_decoder,
+ parent_texture_id);
+}
+
+void GpuScheduler::Destroy() {
+ if (surface_.get()) {
+ surface_->Destroy();
+ surface_.reset();
+ }
+
+ DestroyCommon();
+}
+
+uint64 GpuScheduler::SetWindowSizeForIOSurface(const gfx::Size& size) {
+ // This is called from an IPC handler, so it's undefined which context is
+ // current. Make sure the right one is.
+ decoder_->GetGLContext()->MakeCurrent();
+
+ ResizeOffscreenFrameBuffer(size);
+ decoder_->UpdateOffscreenFrameBufferSize();
+
+ // Note: The following line changes the current context again.
+ return surface_->SetSurfaceSize(size);
+}
+
+TransportDIB::Handle GpuScheduler::SetWindowSizeForTransportDIB(
+ const gfx::Size& size) {
+ ResizeOffscreenFrameBuffer(size);
+ decoder_->UpdateOffscreenFrameBufferSize();
+ return surface_->SetTransportDIBSize(size);
+}
+
+void GpuScheduler::SetTransportDIBAllocAndFree(
+ Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
+ Callback1<TransportDIB::Id>::Type* deallocator) {
+ surface_->SetTransportDIBAllocAndFree(allocator, deallocator);
+}
+
+uint64 GpuScheduler::GetSurfaceId() {
+ if (!surface_.get())
+ return 0;
+ return surface_->GetSurfaceId();
+}
+
+uint64 GpuScheduler::swap_buffers_count() const {
+ return swap_buffers_count_;
+}
+
+void GpuScheduler::set_acknowledged_swap_buffers_count(
+ uint64 acknowledged_swap_buffers_count) {
+ acknowledged_swap_buffers_count_ = acknowledged_swap_buffers_count;
+}
+
+void GpuScheduler::DidDestroySurface() {
+ // When a browser window with a GpuScheduler is closed, the render process
+ // will attempt to finish all GL commands, it will busy-wait on the GPU
+ // process until the command queue is empty. If a paint is pending, the GPU
+ // process won't process any GL commands until the browser sends a paint ack,
+ // but since the browser window is already closed, it will never arrive.
+ // To break this infinite loop, the browser tells the GPU process that the
+ // surface became invalid, which causes the GPU process to not wait for paint
+ // acks.
+ surface_.reset();
+}
+
+void GpuScheduler::WillSwapBuffers() {
+ DCHECK(decoder_.get());
+ DCHECK(decoder_->GetGLContext());
+ DCHECK(decoder_->GetGLContext()->IsCurrent());
+
+ ++swap_buffers_count_;
+
+ if (surface_.get()) {
+ surface_->SwapBuffers();
+ }
+
+ if (wrapped_swap_buffers_callback_.get()) {
+ wrapped_swap_buffers_callback_->Run();
+ }
+}
+
+} // namespace gpu