OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are |
| 7 * met: |
| 8 * |
| 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. |
| 11 * * Redistributions in binary form must reproduce the above |
| 12 * copyright notice, this list of conditions and the following disclaimer |
| 13 * in the documentation and/or other materials provided with the |
| 14 * distribution. |
| 15 * * Neither the name of Google Inc. nor the names of its |
| 16 * contributors may be used to endorse or promote products derived from |
| 17 * this software without specific prior written permission. |
| 18 * |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ |
| 31 |
| 32 |
| 33 #import "plugin_mac.h" |
| 34 #import <OpenGL/OpenGL.h> |
| 35 #import "o3d_layer.h" |
| 36 |
| 37 #include "display_window_mac.h" |
| 38 using o3d::DisplayWindowMac; |
| 39 |
| 40 @implementation O3DLayer |
| 41 |
| 42 |
| 43 - (id)init { |
| 44 self = [super init]; |
| 45 |
| 46 // Set ourselves up to composite correctly. Users can write |
| 47 // arbitrary alpha values into the back buffer but O3D's output is |
| 48 // defined as being opaque. For correct rendering results we must |
| 49 // basically drop the alpha channel while drawing to the screen |
| 50 // using Core Animation. Setting the opaque flag achieves this. |
| 51 if (self != nil) { |
| 52 self.opaque = YES; |
| 53 } |
| 54 |
| 55 return self; |
| 56 } |
| 57 |
| 58 - (void)setPluginObject:(PluginObject *)obj { |
| 59 obj_ = obj; |
| 60 } |
| 61 |
| 62 |
| 63 /* Called when a new frame needs to be generated for layer time 't'. |
| 64 * 'ctx' is attached to the rendering destination. It's state is |
| 65 * otherwise undefined. When non-null 'ts' describes the display |
| 66 * timestamp associated with layer time 't'. The default implementation |
| 67 * of the method flushes the context. */ |
| 68 |
| 69 |
| 70 - (void)drawInCGLContext:(CGLContextObj)ctx |
| 71 pixelFormat:(CGLPixelFormatObj)pf |
| 72 forLayerTime:(CFTimeInterval)t |
| 73 displayTime:(const CVTimeStamp *)ts { |
| 74 |
| 75 // Set the current context to the one given to us. |
| 76 CGLSetCurrentContext(ctx); |
| 77 |
| 78 if (created_context_) { |
| 79 DCHECK_EQ(ctx, obj_->mac_cgl_context_); |
| 80 o3d::DisplayWindowMac default_display; |
| 81 default_display.set_agl_context(obj_->mac_agl_context_); |
| 82 default_display.set_cgl_context(obj_->mac_cgl_context_); |
| 83 obj_->CreateRenderer(default_display); |
| 84 obj_->client()->Init(); |
| 85 created_context_ = false; |
| 86 } |
| 87 |
| 88 if (was_resized_) { |
| 89 obj_->Resize(width_, height_); |
| 90 was_resized_ = false; |
| 91 } |
| 92 |
| 93 |
| 94 if (obj_) { |
| 95 obj_->client()->Tick(); |
| 96 obj_->client()->RenderClient(true); |
| 97 } |
| 98 |
| 99 // Call super to finalize the drawing. By default it just calls glFlush(). |
| 100 [super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts]; |
| 101 } |
| 102 |
| 103 - (BOOL)canDrawInCGLContext:(CGLContextObj)ctx |
| 104 pixelFormat:(CGLPixelFormatObj)pf |
| 105 forLayerTime:(CFTimeInterval)t |
| 106 displayTime:(const CVTimeStamp *)ts { |
| 107 return YES; |
| 108 } |
| 109 |
| 110 |
| 111 |
| 112 |
| 113 /* Called by the CAOpenGLLayer implementation when a rendering context |
| 114 * is needed by the layer. Should return an OpenGL context with |
| 115 * renderers from pixel format 'pixelFormat'. The default implementation |
| 116 * allocates a new context with a null share context. */ |
| 117 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat { |
| 118 glContext_ = [super copyCGLContextForPixelFormat:pixelFormat]; |
| 119 obj_->mac_cgl_context_ = glContext_; |
| 120 created_context_ = true; |
| 121 |
| 122 return glContext_; |
| 123 } |
| 124 |
| 125 /* |
| 126 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { |
| 127 return [super copyCGLPixelFormatForDisplayMask:mask]; |
| 128 }*/ |
| 129 |
| 130 |
| 131 #define PFA(number) static_cast<CGLPixelFormatAttribute>(number) |
| 132 |
| 133 #define O3D_COLOR_AND_DEPTH_SETTINGS kCGLPFAClosestPolicy, \ |
| 134 kCGLPFAColorSize, PFA(24), \ |
| 135 kCGLPFAAlphaSize, PFA(8), \ |
| 136 kCGLPFADepthSize, PFA(24), \ |
| 137 kCGLPFADoubleBuffer, |
| 138 #define O3D_STENCIL_SETTINGS kCGLPFAStencilSize, PFA(8), |
| 139 #define O3D_HARDWARE_RENDERER kCGLPFAAccelerated, kCGLPFANoRecovery, |
| 140 #define O3D_MULTISAMPLE kCGLPFAMultisample, kCGLPFASamples, PFA(4), |
| 141 #define O3D_DISPLAY_MASK(mask) kCGLPFADisplayMask, PFA(mask), |
| 142 #define O3D_END PFA(0) |
| 143 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { |
| 144 const CGLPixelFormatAttribute attributes[] = { |
| 145 O3D_COLOR_AND_DEPTH_SETTINGS |
| 146 O3D_STENCIL_SETTINGS |
| 147 O3D_HARDWARE_RENDERER |
| 148 O3D_DISPLAY_MASK(mask) |
| 149 O3D_MULTISAMPLE |
| 150 O3D_END |
| 151 }; |
| 152 CGLPixelFormatObj pixel_format = NULL; |
| 153 GLint num_screens = 0; |
| 154 if (!CGLChoosePixelFormat(attributes, &pixel_format, &num_screens) && |
| 155 pixel_format) { |
| 156 return pixel_format; |
| 157 } else { |
| 158 // Try a less capable set. |
| 159 static const CGLPixelFormatAttribute low_end_attributes[] = { |
| 160 O3D_COLOR_AND_DEPTH_SETTINGS |
| 161 O3D_STENCIL_SETTINGS |
| 162 O3D_HARDWARE_RENDERER |
| 163 O3D_DISPLAY_MASK(mask) |
| 164 O3D_END |
| 165 }; |
| 166 if (!CGLChoosePixelFormat(low_end_attributes, |
| 167 &pixel_format, &num_screens) && pixel_format) { |
| 168 return pixel_format; |
| 169 } else { |
| 170 // Do whatever the superclass supports. |
| 171 return [super copyCGLPixelFormatForDisplayMask:mask]; |
| 172 } |
| 173 } |
| 174 } |
| 175 |
| 176 |
| 177 - (CGLContextObj)glContext { |
| 178 return glContext_; |
| 179 } |
| 180 |
| 181 - (void)setWidth:(int)width height:(int)height { |
| 182 width_ = width; |
| 183 height_ = height; |
| 184 was_resized_ = true; |
| 185 } |
| 186 |
| 187 @end |
OLD | NEW |