Index: content/common/gpu/image_transport_surface_calayer_mac.mm |
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.mm b/content/common/gpu/image_transport_surface_calayer_mac.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1235c60360a01d423745c89de597ff65578bcac6 |
--- /dev/null |
+++ b/content/common/gpu/image_transport_surface_calayer_mac.mm |
@@ -0,0 +1,172 @@ |
+// 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/common/gpu/image_transport_surface_mac.h" |
+ |
+#include "base/mac/scoped_nsobject.h" |
+#include "content/common/gpu/gpu_messages.h" |
+#include "ui/base/cocoa/remote_layer_api.h" |
+#include "ui/gl/scoped_cgl.h" |
+ |
+@interface ImageTransportLayer : CAOpenGLLayer { |
+ base::ScopedTypeRef<CGLContextObj> context_; |
+ gfx::Size size_; |
+ GLuint texture_; |
+} |
+ |
+- (void)setTexture:(GLuint)texture withSize:(gfx::Size)size; |
+@end |
+ |
+@implementation ImageTransportLayer |
+ |
+- (id)initWithContext:(CGLContextObj)context { |
+ if (self = [super init]) { |
+ context_.reset(CGLRetainContext(context)); |
+ texture_ = 0; |
+ } |
+ return self; |
+} |
+ |
+- (void)setTexture:(GLuint)texture withSize:(gfx::Size)size { |
+ size_ = size; |
+ texture_ = texture; |
+} |
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { |
+ return CGLRetainPixelFormat(CGLGetPixelFormat(context_)); |
+} |
+ |
+- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat { |
+ CGLContextObj result = NULL; |
+ CGLCreateContext(pixelFormat, context_, &result); |
+ return result; |
+} |
+ |
+- (void)drawInCGLContext:(CGLContextObj)glContext |
+ pixelFormat:(CGLPixelFormatObj)pixelFormat |
+ forLayerTime:(CFTimeInterval)timeInterval |
+ displayTime:(const CVTimeStamp*)timeStamp { |
+ static float t = 0; |
+ t += 0.1; |
+ glClearColor(0, 0.5 + 0.5 * cosf(t), 0, 1); |
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
+ |
+ glMatrixMode(GL_PROJECTION); |
+ glLoadIdentity(); |
+ glOrtho(-1.1, 1.1, -1.1, 1.1, -1.1, 1.1); |
+ |
+ glMatrixMode(GL_MODELVIEW); |
+ glLoadIdentity(); |
+ |
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_); |
+ glEnable(GL_TEXTURE_RECTANGLE_ARB); |
+ glColor3f(1, 1, 1); |
+ glBegin(GL_QUADS); |
+ glTexCoord2f(0, 0); |
+ glVertex2f(-1, -1); |
+ |
+ glTexCoord2f(0, size_.height()-1); |
+ glVertex2f(-1, 1); |
+ |
+ glTexCoord2f(size_.width()-1, size_.height()-1); |
+ glVertex2f( 1, 1); |
+ |
+ glTexCoord2f(size_.width()-1, 0); |
+ glVertex2f( 1, -1); |
+ glEnd(); |
+ |
+ [super drawInCGLContext:glContext |
+ pixelFormat:pixelFormat |
+ forLayerTime:timeInterval |
+ displayTime:timeStamp]; |
+} |
+ |
+@end |
+ |
+namespace content { |
+ |
+// We are backed by an offscreen surface for the purposes of creating |
+// a context, but use FBOs to render to texture backed IOSurface |
+class CALayerStorageProvider |
+ : public ImageTransportSurfaceFBO::StorageProvider { |
+ public: |
+ CALayerStorageProvider(); |
+ virtual ~CALayerStorageProvider(); |
+ |
+ // ImageTransportSurfaceFBO::StorageProvider implementation: |
+ virtual gfx::Size GetRoundedSize(gfx::Size size) OVERRIDE; |
+ virtual bool AllocateColorBufferStorage( |
+ CGLContextObj context, gfx::Size size) OVERRIDE; |
+ virtual void FreeColorBufferStorage() OVERRIDE; |
+ virtual void PopulateSwapBuffersStorageParams( |
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params* params) OVERRIDE; |
+ virtual void PopulateSubBufferStorageParams( |
+ GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params* params) OVERRIDE; |
+ |
+ private: |
+ base::scoped_nsobject<ImageTransportLayer> layer_; |
+ base::scoped_nsobject<CAContext> context_; |
+}; |
+ |
+CALayerStorageProvider::CALayerStorageProvider() { |
+} |
+ |
+CALayerStorageProvider::~CALayerStorageProvider() { |
+} |
+ |
+gfx::Size CALayerStorageProvider::GetRoundedSize(gfx::Size size) { |
+ return size; |
+} |
+ |
+bool CALayerStorageProvider::AllocateColorBufferStorage( |
+ CGLContextObj context, gfx::Size size) { |
+ NSDictionary* dict = [[NSDictionary alloc] init]; |
+ CGSConnectionID connection_id = CGSMainConnectionID(); |
+ context_.reset([CAContext contextWithCGSConnection:connection_id options:dict]); |
+ [context_ retain]; |
+ |
+ layer_.reset([[ImageTransportLayer alloc] initWithContext:context]); |
+ [layer_ setFrame:CGRectMake(0, 0, size.width() / 2, size.height() / 2)]; |
+ [context_ setLayer:layer_]; |
+ |
+ GLint texture; |
+ glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &texture); |
+ [layer_ setTexture:texture withSize:size]; |
+ |
+ glTexImage2D( |
+ GL_TEXTURE_RECTANGLE_ARB, |
+ 0, |
+ GL_RGBA, |
+ size.width(), |
+ size.height(), |
+ 0, |
+ GL_RGBA, |
+ GL_UNSIGNED_BYTE, |
+ NULL); |
+ |
+ return true; |
+} |
+ |
+void CALayerStorageProvider::FreeColorBufferStorage() { |
+ [context_ setLayer:nil]; |
+ context_.reset(); |
+ layer_.reset(); |
+} |
+ |
+void CALayerStorageProvider::PopulateSwapBuffersStorageParams( |
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params* params) { |
+ params->ca_context_id = [context_ contextId]; |
+ [layer_ setNeedsDisplay]; |
+} |
+ |
+void CALayerStorageProvider::PopulateSubBufferStorageParams( |
+ GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params* params) { |
+ params->ca_context_id = [context_ contextId]; |
+} |
+ |
+ImageTransportSurfaceFBO::StorageProvider* MakeThing() { |
+ return new CALayerStorageProvider; |
+} |
+ |
+} // namespace content |
+ |