15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/image_transport_surface.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_cftyperef.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "content/common/gpu/gpu_command_buffer_stub.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface_cgl.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_surface_osmesa.h" 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/gl/io_surface_support_mac.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IOSurface dimensions will be rounded up to a multiple of this value in order 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to reduce memory thrashing during resize. This must be a power of 2. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint32 kIOSurfaceDimensionRoundup = 64; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RoundUpSurfaceDimension(int number) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(number >= 0); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cast into unsigned space for portable bitwise ops. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 unsigned_number = static_cast<uint32>(number); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 roundup_sub_1 = kIOSurfaceDimensionRoundup - 1; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned_number = (unsigned_number + roundup_sub_1) & ~roundup_sub_1; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(unsigned_number); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We are backed by an offscreen surface for the purposes of creating 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a context, but use FBOs to render to texture backed IOSurface 375e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class IOSurfaceImageTransportSurface 385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) : public gfx::NoOpGLSurfaceCGL, 395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) public ImageTransportSurface, 405e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) public GpuCommandBufferStub::DestructionObserver { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IOSurfaceImageTransportSurface(GpuChannelManager* manager, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* stub, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::PluginWindowHandle handle); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GLSurface implementation 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Initialize() OVERRIDE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Destroy() OVERRIDE; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool DeferDraws() OVERRIDE; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsOffscreen() OVERRIDE; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool SwapBuffers() OVERRIDE; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::string GetExtensions() OVERRIDE; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Size GetSize() OVERRIDE; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool SetBackbufferAllocation(bool allocated) OVERRIDE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetFrontbufferAllocation(bool allocated) OVERRIDE; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ImageTransportSurface implementation 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnBufferPresented( 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnResizeViewACK() OVERRIDE; 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnResize(gfx::Size size, float scale_factor) OVERRIDE; 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void SetLatencyInfo(const ui::LatencyInfo&) OVERRIDE; 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void WakeUpGpu() OVERRIDE; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // GpuCommandBufferStub::DestructionObserver implementation. 705e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) virtual void OnWillDestroyStub() OVERRIDE; 715e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IOSurfaceImageTransportSurface() OVERRIDE; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AdjustBufferAllocation(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnrefIOSurface(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateIOSurface(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tracks the current buffer allocation state. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool backbuffer_suggested_allocation_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool frontbuffer_suggested_allocation_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 fbo_id_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint texture_id_; 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GLuint depth_stencil_renderbuffer_id_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFTypeRef> io_surface_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The id of |io_surface_| or 0 if that's NULL. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 io_surface_handle_; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Weak pointer to the context that this was last made current to. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLContext* context_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size rounded_size_; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) float scale_factor_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether or not we've successfully made the surface current once. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool made_current_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether a SwapBuffers is pending. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_swap_buffers_pending_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether we unscheduled command buffer because of pending SwapBuffers. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_unschedule_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::LatencyInfo latency_info_; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ImageTransportHelper> helper_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddBooleanValue(CFMutableDictionaryRef dictionary, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CFStringRef key, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool value) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDictionaryAddValue(dictionary, key, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (value ? kCFBooleanTrue : kCFBooleanFalse)); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddIntegerValue(CFMutableDictionaryRef dictionary, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CFStringRef key, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 value) { 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFNumberRef> number( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDictionaryAddValue(dictionary, key, number.get()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* stub, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::PluginWindowHandle handle) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backbuffer_suggested_allocation_(true), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frontbuffer_suggested_allocation_(true), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fbo_id_(0), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_id_(0), 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) depth_stencil_renderbuffer_id_(0), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_handle_(0), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_(NULL), 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scale_factor_(1.f), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_current_(false), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_swap_buffers_pending_(false), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_unschedule_(false) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::Initialize() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only support IOSurfaces if the GL implementation is the native desktop GL. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IO surfaces will not work with, for example, OSMesa software renderer 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GL contexts. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL && 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!helper_->Initialize()) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1625e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1635e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (!NoOpGLSurfaceCGL::Initialize()) { 1645e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) helper_->Destroy(); 1655e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return false; 1665e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 1675e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 1685e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) helper_->stub()->AddDestructionObserver(this); 1695e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return true; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::Destroy() { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnrefIOSurface(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->Destroy(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoOpGLSurfaceCGL::Destroy(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::DeferDraws() { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The command buffer hit a draw/clear command that could clobber the 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IOSurface in use by an earlier SwapBuffers. If a Swap is pending, abort 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // processing of the command by returning true and unschedule until the Swap 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ack arrives. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(did_unschedule_) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // Still unscheduled, so just return true. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_swap_buffers_pending_) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_unschedule_ = true; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->SetScheduled(false); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::IsOffscreen() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = context; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (made_current_) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResize(gfx::Size(1, 1), 1.f); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) made_current_ = true; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fbo_id_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IOSurfaceImageTransportSurface::SetBackbufferAllocation(bool allocation) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (backbuffer_suggested_allocation_ == allocation) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backbuffer_suggested_allocation_ = allocation; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdjustBufferAllocation(); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frontbuffer_suggested_allocation_ == allocation) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frontbuffer_suggested_allocation_ = allocation; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdjustBufferAllocation(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::AdjustBufferAllocation() { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // free'd when both the browser and gpu processes have Unref'd the IOSurface. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backbuffer_suggested_allocation_ && 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !frontbuffer_suggested_allocation_ && 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_.get()) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnrefIOSurface(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->Suspend(); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (backbuffer_suggested_allocation_ && !io_surface_) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateIOSurface(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::SwapBuffers() { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backbuffer_suggested_allocation_); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!frontbuffer_suggested_allocation_) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glFlush(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.surface_handle = io_surface_handle_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.size = GetSize(); 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.scale_factor = scale_factor_; 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.latency_info = latency_info_; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->SendAcceleratedSurfaceBuffersSwapped(params); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_swap_buffers_pending_); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_swap_buffers_pending_ = true; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IOSurfaceImageTransportSurface::PostSubBuffer( 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int width, int height) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backbuffer_suggested_allocation_); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!frontbuffer_suggested_allocation_) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glFlush(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.surface_handle = io_surface_handle_; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.x = x; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.y = y; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.width = width; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.height = height; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.surface_size = GetSize(); 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.surface_scale_factor = scale_factor_; 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.latency_info = latency_info_; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->SendAcceleratedSurfacePostSubBuffer(params); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_swap_buffers_pending_); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_swap_buffers_pending_ = true; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IOSurfaceImageTransportSurface::GetExtensions() { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extensions = gfx::GLSurface::GetExtensions(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions += extensions.empty() ? "" : " "; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions += "GL_CHROMIUM_front_buffer_cached "; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions += "GL_CHROMIUM_post_sub_buffer"; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extensions; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size IOSurfaceImageTransportSurface::GetSize() { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IOSurfaceImageTransportSurface::OnBufferPresented( 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AcceleratedSurfaceMsg_BufferPresented_Params& params) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_swap_buffers_pending_); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_->share_group()->SetRendererID(params.renderer_id); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_swap_buffers_pending_ = false; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (did_unschedule_) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_unschedule_ = false; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_->SetScheduled(true); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::OnResizeViewACK() { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IOSurfaceImageTransportSurface::OnResize(gfx::Size size, 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) float scale_factor) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This trace event is used in gpu_feature_browsertest.cc - the test will need 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be updated if this event is changed or moved. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::OnResize", 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "old_width", size_.width(), "new_width", size.width()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Caching |context_| from OnMakeCurrent. It should still be current. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(context_->IsCurrent(this)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = size; 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scale_factor_ = scale_factor; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateIOSurface(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IOSurfaceImageTransportSurface::SetLatencyInfo( 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ui::LatencyInfo& latency_info) { 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) latency_info_ = latency_info; 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void IOSurfaceImageTransportSurface::WakeUpGpu() { 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTIMPLEMENTED(); 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3355e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void IOSurfaceImageTransportSurface::OnWillDestroyStub() { 3365e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) helper_->stub()->RemoveDestructionObserver(this); 3375e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) Destroy(); 3385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 3395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::UnrefIOSurface() { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have resources to destroy, then make sure that we have a current 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // context which we can use to delete the resources. 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (context_ || fbo_id_ || texture_id_ || depth_stencil_renderbuffer_id_) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(gfx::GLContext::GetCurrent() == context_); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context_->IsCurrent(this)); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CGLGetCurrentContext()); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fbo_id_) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glDeleteFramebuffersEXT(1, &fbo_id_); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fbo_id_ = 0; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_id_) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glDeleteTextures(1, &texture_id_); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_id_ = 0; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (depth_stencil_renderbuffer_id_) { 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) depth_stencil_renderbuffer_id_ = 0; 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_.reset(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_handle_ = 0; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IOSurfaceImageTransportSurface::CreateIOSurface() { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size new_rounded_size(RoundUpSurfaceDimension(size_.width()), 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RoundUpSurfaceDimension(size_.height())); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only recreate surface when the rounded up size has changed. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (io_surface_.get() && new_rounded_size == rounded_size_) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This trace event is used in gpu_feature_browsertest.cc - the test will need 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be updated if this event is changed or moved. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::CreateIOSurface", 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "width", new_rounded_size.width(), 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "height", new_rounded_size.height()); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rounded_size_ = new_rounded_size; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint previous_texture_id = 0; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Free the old IO Surface first to reduce memory fragmentation. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnrefIOSurface(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGenFramebuffersEXT(1, &fbo_id_); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGenTextures(1, &texture_id_); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mac OS X and is required for IOSurface interoperability. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum target = GL_TEXTURE_RECTANGLE_ARB; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glBindTexture(target, texture_id_); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_COLOR_ATTACHMENT0_EXT, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_id_, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Search through the provided attributes; if the caller has 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // requested a stencil buffer, try to get one. 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int32 stencil_bits = 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) helper_->stub()->GetRequestedAttribute(EGL_STENCIL_SIZE); 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (stencil_bits > 0) { 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create and bind the stencil buffer 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool has_packed_depth_stencil = 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GLSurface::ExtensionsContain( 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)), 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "GL_EXT_packed_depth_stencil"); 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (has_packed_depth_stencil) { 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) depth_stencil_renderbuffer_id_); 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rounded_size_.width(), rounded_size_.height()); 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GL_STENCIL_ATTACHMENT_EXT, 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GL_RENDERBUFFER_EXT, 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) depth_stencil_renderbuffer_id_); 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If we asked for stencil but the extension isn't present, 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // it's OK to silently fail; subsequent code will/must check 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // for the presence of a stencil buffer before attempting to 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // do stencil-based operations. 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a new IOSurface, which is the GPU resource that can be 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shared across processes. 445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks)); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddIntegerValue(properties, 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_support->GetKIOSurfaceWidth(), 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rounded_size_.width()); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddIntegerValue(properties, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_support->GetKIOSurfaceHeight(), 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rounded_size_.height()); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddIntegerValue(properties, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_support->GetKIOSurfaceBytesPerElement(), 4); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddBooleanValue(properties, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_support->GetKIOSurfaceIsGlobal(), true); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I believe we should be able to unreference the IOSurfaces without 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronizing with the browser process because they are 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ultimately reference counted by the operating system. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't think we need to identify a plane. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint plane = 0; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CGLError cglerror = 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_support->CGLTexImageIOSurface2D( 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<CGLContextObj>(context_->GetHandle()), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target, 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_RGBA, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rounded_size_.width(), 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rounded_size_.height(), 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_BGRA, 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_UNSIGNED_INT_8_8_8_8_REV, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_surface_.get(), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plane); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cglerror != kCGLNoError) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnrefIOSurface(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glFlush(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DLOG(ERROR) << "Framebuffer was incomplete: " << status; 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnrefIOSurface(); 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glBindTexture(target, previous_texture_id); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The FBO remains bound for this GL context. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A subclass of GLSurfaceOSMesa that doesn't print an error message when 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SwapBuffers() is called. 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DRTSurfaceOSMesa : public gfx::GLSurfaceOSMesa { 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Size doesn't matter, the surface is resized to the right size later. 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DRTSurfaceOSMesa() : GLSurfaceOSMesa(GL_RGBA, gfx::Size(1, 1)) {} 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Implement a subset of GLSurface. 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool SwapBuffers() OVERRIDE; 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DRTSurfaceOSMesa() {} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DRTSurfaceOSMesa); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DRTSurfaceOSMesa::SwapBuffers() { 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_allow_os_mesa = false; 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager, 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* stub, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::GLSurfaceHandle& surface_handle) { 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(surface_handle.transport_type == gfx::NATIVE_TRANSPORT); 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (gfx::GetGLImplementation()) { 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case gfx::kGLImplementationDesktopGL: 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case gfx::kGLImplementationAppleGL: 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!io_surface_support) { 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(WARNING) << "No IOSurface support"; 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_refptr<gfx::GLSurface>(); 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_refptr<gfx::GLSurface>(new IOSurfaceImageTransportSurface( 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager, stub, surface_handle.handle)); 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Content shell in DRT mode spins up a gpu process which needs an 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // image transport surface, but that surface isn't used to read pixel 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // baselines. So this is mostly a dummy surface. 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!g_allow_os_mesa) { 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_refptr<gfx::GLSurface>(); 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa()); 5477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!surface.get() || !surface->Initialize()) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return surface; 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface( 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager, stub, surface.get(), false)); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_allow_os_mesa = allow; 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 560