summaryrefslogtreecommitdiffstats
path: root/o3d/plugin
diff options
context:
space:
mode:
authormaf@google.com <maf@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 21:15:48 +0000
committermaf@google.com <maf@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 21:15:48 +0000
commit56967ecd6eeca05f1267b98ccded1e17ca0ea80a (patch)
tree8e85bda96060f644c099eaecbec07234dfc9ae99 /o3d/plugin
parentf8f72875acb86d0a307d759269ee005d7327343d (diff)
downloadchromium_src-56967ecd6eeca05f1267b98ccded1e17ca0ea80a.zip
chromium_src-56967ecd6eeca05f1267b98ccded1e17ca0ea80a.tar.gz
chromium_src-56967ecd6eeca05f1267b98ccded1e17ca0ea80a.tar.bz2
Review URL: http://codereview.chromium.org/577038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44397 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/plugin')
-rw-r--r--o3d/plugin/cross/o3d_glue.cc1
-rw-r--r--o3d/plugin/cross/o3d_glue.h1
-rw-r--r--o3d/plugin/mac/graphics_utils_mac.h2
-rw-r--r--o3d/plugin/mac/graphics_utils_mac.mm18
-rw-r--r--o3d/plugin/mac/main_mac.mm153
-rw-r--r--o3d/plugin/mac/o3d_layer.h61
-rw-r--r--o3d/plugin/mac/o3d_layer.mm187
-rw-r--r--o3d/plugin/mac/plugin_mac.mm11
-rw-r--r--o3d/plugin/plugin.gyp2
9 files changed, 390 insertions, 46 deletions
diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc
index 0d66e9c..a2b7ef5 100644
--- a/o3d/plugin/cross/o3d_glue.cc
+++ b/o3d/plugin/cross/o3d_glue.cc
@@ -142,6 +142,7 @@ PluginObject::PluginObject(NPP npp)
mac_cgl_context_(0),
mac_cgl_pbuffer_(0),
last_mac_event_time_(0),
+ gl_layer_(NULL),
#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG
time_to_hide_overlay_(0.0),
#endif
diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h
index c335665..4448ecd 100644
--- a/o3d/plugin/cross/o3d_glue.h
+++ b/o3d/plugin/cross/o3d_glue.h
@@ -275,6 +275,7 @@ class PluginObject: public NPObject {
// either can be NULL depending on drawing_model
AGLContext mac_agl_context_;
CGLContextObj mac_cgl_context_;
+ void *gl_layer_;
// If in Chrome, we actually do all of our rendering offscreen, and
// bootstrap off a 1x1 pbuffer
CGLPBufferObj mac_cgl_pbuffer_;
diff --git a/o3d/plugin/mac/graphics_utils_mac.h b/o3d/plugin/mac/graphics_utils_mac.h
index 710e683..bfa408c 100644
--- a/o3d/plugin/mac/graphics_utils_mac.h
+++ b/o3d/plugin/mac/graphics_utils_mac.h
@@ -48,6 +48,8 @@ bool SetWindowForAGLContext(AGLContext context, WindowRef window);
bool IsMacOSTenFiveOrHigher();
+bool IsMacOSTenSixOrHigher();
+
Rect CGRect2Rect(const CGRect &inRect);
CGRect Rect2CGRect(const Rect &inRect);
diff --git a/o3d/plugin/mac/graphics_utils_mac.mm b/o3d/plugin/mac/graphics_utils_mac.mm
index 4b8b45f90..34bb36f 100644
--- a/o3d/plugin/mac/graphics_utils_mac.mm
+++ b/o3d/plugin/mac/graphics_utils_mac.mm
@@ -82,7 +82,23 @@ bool IsMacOSTenFiveOrHigher() {
}
return result;
}
-
+
+// Returns whether OS is 10.6 (Snow Leopard) or higher.
+bool IsMacOSTenSixOrHigher() {
+ static bool isCached = false, result = false;
+
+ if (!isCached) {
+ SInt32 major = 0;
+ SInt32 minor = 0;
+ // These selectors don't exist pre 10.4 but as we check the error
+ // the function will correctly return NO which is the right answer.
+ result = ((::Gestalt(gestaltSystemVersionMajor, &major) == noErr) &&
+ (::Gestalt(gestaltSystemVersionMinor, &minor) == noErr) &&
+ ((major > 10) || (major == 10 && minor >= 6)));
+ isCached = true;
+ }
+ return result;
+}
Rect CGRect2Rect(const CGRect &inRect) {
Rect outRect;
diff --git a/o3d/plugin/mac/main_mac.mm b/o3d/plugin/mac/main_mac.mm
index a07b32f..617c906 100644
--- a/o3d/plugin/mac/main_mac.mm
+++ b/o3d/plugin/mac/main_mac.mm
@@ -48,6 +48,7 @@
#include "core/cross/event.h"
#include "statsreport/metrics.h"
+#include "plugin/cross/config.h"
#include "plugin/cross/plugin_logging.h"
#include "plugin/cross/plugin_metrics.h"
#include "plugin/cross/o3d_glue.h"
@@ -55,6 +56,8 @@
#include "plugin/cross/whitelist.h"
#include "plugin/mac/plugin_mac.h"
#include "plugin/mac/graphics_utils_mac.h"
+#import "plugin/mac/o3d_layer.h"
+
#if !defined(O3D_INTERNAL_PLUGIN)
o3d::PluginLogging* g_logger = NULL;
@@ -80,6 +83,15 @@ base::AtExitManager g_at_exit_manager;
#define CFTIMER
// #define DEFERRED_DRAW_ON_NULLEVENTS
+
+// Helper that extracts the O3DLayer obj c object from the PluginObject
+// and coerces it to the right type. The code can't live in the PluginObject
+// since it's c++ code and doesn't know about objective c types, and it saves
+// lots of casts elsewhere in the code.
+static O3DLayer* ObjO3DLayer(PluginObject* obj) {
+ return static_cast<O3DLayer*>(obj ? obj->gl_layer_ : nil);
+}
+
void DrawPlugin(PluginObject* obj, bool send_callback, CGContextRef context) {
obj->client()->RenderClient(send_callback);
Renderer* renderer = obj->renderer();
@@ -468,9 +480,16 @@ bool HandleCocoaEvent(NPP instance, NPCocoaEvent* the_event) {
case NPCocoaEventDrawRect:
// We need to call the render callback from here if we are rendering
// off-screen because it doesn't get called anywhere else.
- DrawPlugin(obj,
- obj->IsOffscreenRenderingEnabled(),
- the_event->data.draw.context);
+ if (obj->drawing_model_ == NPDrawingModelCoreAnimation) {
+ O3DLayer* layer = ObjO3DLayer(obj);
+ if (layer) {
+ [layer setNeedsDisplay];
+ }
+ } else {
+ DrawPlugin(obj,
+ obj->IsOffscreenRenderingEnabled(),
+ the_event->data.draw.context);
+ }
handled = true;
break;
case NPCocoaEventMouseDown:
@@ -584,6 +603,13 @@ NPError InitializePlugin() {
return NPERR_NO_ERROR;
}
+// When to prefer Core Animation, currently that's only on Safari and 10.6+
+// but that will change as we use this model in more browsers.
+static bool PreferCoreAnimation() {
+ bool isSafari = o3d::metric_browser_type.value() == o3d::BROWSER_NAME_SAFARI;
+ return (o3d::IsMacOSTenSixOrHigher() && isSafari);
+}
+
// Negotiates the best plugin event model, sets the browser to use that,
// and updates the PluginObject so we can remember which one we chose.
// We favor the newer Cocoa-based model, but can cope with browsers that
@@ -628,19 +654,31 @@ void Mac_SetBestEventModel(NPP instance, PluginObject* obj) {
obj->event_model_ = NPEventModelCarbon;
}
- // Default to Carbon event model, because the new version of the
- // Cocoa event model spec does not supply sufficient window
- // information in its Cocoa NPP_SetWindow calls for us to bind an
- // AGL context to the browser window.
- model_to_use =
- (supportsCarbonEventModel) ? NPEventModelCarbon : NPEventModelCocoa;
- if (o3d::gIsChrome) {
- if (supportsCocoaEventModel) {
- model_to_use = NPEventModelCocoa;
+
+ if (PreferCoreAnimation()) {
+ // If we're building for Core Animation then we prefer the Cocoa event
+ // model.
+ model_to_use =
+ (supportsCocoaEventModel) ? NPEventModelCocoa : NPEventModelCarbon;
+ NPN_SetValue(instance, NPPVpluginEventModel,
+ reinterpret_cast<void*>(model_to_use));
+ } else {
+ // Default to Carbon event model, because the new version of the
+ // Cocoa event model spec does not supply sufficient window
+ // information in its Cocoa NPP_SetWindow calls for us to bind an
+ // AGL context to the browser window.
+ model_to_use =
+ (supportsCarbonEventModel) ? NPEventModelCarbon : NPEventModelCocoa;
+ if (o3d::gIsChrome) {
+ if (supportsCocoaEventModel) {
+ model_to_use = NPEventModelCocoa;
+ }
}
}
NPN_SetValue(instance, NPPVpluginEventModel,
reinterpret_cast<void*>(model_to_use));
+
+
obj->event_model_ = model_to_use;
}
@@ -651,17 +689,10 @@ void Mac_SetBestEventModel(NPP instance, PluginObject* obj) {
NPError Mac_SetBestDrawingModel(NPP instance, PluginObject* obj) {
NPError err = NPERR_NO_ERROR;
NPBool supportsCoreGraphics = FALSE;
- NPBool supportsOpenGL = FALSE;
NPBool supportsQuickDraw = FALSE;
+ NPBool supportsCoreAnimation = FALSE;
NPDrawingModel drawing_model = NPDrawingModelQuickDraw;
- // test for direct OpenGL support
- err = NPN_GetValue(instance,
- NPNVsupportsOpenGLBool,
- &supportsOpenGL);
- if (err != NPERR_NO_ERROR)
- supportsOpenGL = FALSE;
-
// test for QuickDraw support
err = NPN_GetValue(instance,
NPNVsupportsQuickDrawBool,
@@ -676,23 +707,27 @@ NPError Mac_SetBestDrawingModel(NPP instance, PluginObject* obj) {
if (err != NPERR_NO_ERROR)
supportsCoreGraphics = FALSE;
+ err = NPN_GetValue(instance,
+ NPNVsupportsCoreAnimationBool,
+ &supportsCoreAnimation);
+ if (err != NPERR_NO_ERROR)
+ supportsCoreAnimation = FALSE;
+
+ // In order of preference. Preference is now determined by compatibility,
+ // not by modernity, and so is the opposite of the order I first used.
+ if (supportsQuickDraw && !(obj->event_model_ == NPEventModelCocoa)) {
+ drawing_model = NPDrawingModelQuickDraw;
+ } else if (supportsCoreAnimation && PreferCoreAnimation()) {
+ drawing_model = NPDrawingModelCoreAnimation;
// In the Chrome browser we currently want to prefer the CoreGraphics
// drawing model, read back the frame buffer into system memory and draw
// the results to the screen using CG.
//
- // TODO(maf): Once support for the CoreAnimation drawing model is
- // integrated into O3D, we will want to revisit this logic.
- if (o3d::gIsChrome && supportsCoreGraphics) {
+ } else if (o3d::gIsChrome && supportsCoreGraphics) {
drawing_model = NPDrawingModelCoreGraphics;
} else {
- // In order of preference. Preference is now determined by compatibility,
- // not by modernity, and so is the opposite of the order I first used.
- if (supportsQuickDraw && !(obj->event_model_ == NPEventModelCocoa)) {
- drawing_model = NPDrawingModelQuickDraw;
- } else if (supportsCoreGraphics) {
+ if (supportsCoreGraphics) {
drawing_model = NPDrawingModelCoreGraphics;
- } else if (supportsOpenGL) {
- drawing_model = NPDrawingModelOpenGL;
} else {
// This case is for browsers that didn't even understand the question
// eg FF2, so drawing models are not supported, just assume QuickDraw.
@@ -779,9 +814,32 @@ NPError OSCALL NP_Shutdown(void) {
} // namespace o3d / extern "C"
+
namespace o3d {
NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) {
+ PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+
+ switch (variable) {
+ case NPPVpluginCoreAnimationLayer:
+ if (!ObjO3DLayer(obj)) {
+ // Setup layer
+ O3DLayer* gl_layer = [[[O3DLayer alloc] init] retain];
+
+ gl_layer.autoresizingMask =
+ kCALayerWidthSizable + kCALayerHeightSizable;
+ obj->gl_layer_ = gl_layer;
+
+ [gl_layer setPluginObject:obj];
+ }
+ // Make sure to return a retained layer
+ *(CALayer**)value = ObjO3DLayer(obj);
+ return NPERR_NO_ERROR;
+ break;
+ default:
+ return NPERR_INVALID_PARAM;
+ }
+
return NPERR_INVALID_PARAM;
}
@@ -883,7 +941,7 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
#if !defined(O3D_INTERNAL_PLUGIN)
if (!g_logging_initialized) {
- GetUserAgentMetrics(instance);
+ o3d::GetUserAgentMetrics(instance);
GetUserConfigMetrics();
// Create usage stats logs object
g_logger = o3d::PluginLogging::InitializeUsageStatsLogging();
@@ -908,6 +966,11 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
instance, static_cast<PluginObject*>(instance->pdata));
if (err != NPERR_NO_ERROR)
return err;
+#ifdef CFTIMER
+ if (pluginObject->drawing_model_ == NPDrawingModelCoreAnimation) {
+ o3d::gRenderTimer.AddInstance(instance);
+ }
+#endif
return NPERR_NO_ERROR;
}
@@ -939,24 +1002,19 @@ NPError NPP_SetWindow(NPP instance, NPWindow* window) {
assert(window != NULL);
if (window->window == NULL &&
- obj->drawing_model_ != NPDrawingModelCoreGraphics)
+ obj->drawing_model_ != NPDrawingModelCoreGraphics &&
+ obj->drawing_model_!= NPDrawingModelCoreAnimation) {
return NPERR_NO_ERROR;
+ }
obj->last_plugin_loc_.h = window->x;
obj->last_plugin_loc_.v = window->y;
switch (obj->drawing_model_) {
- case NPDrawingModelOpenGL: {
- NP_GLContext* np_gl = reinterpret_cast<NP_GLContext*>(window->window);
- if (obj->event_model_ == NPEventModelCocoa) {
- NSWindow * ns_window = reinterpret_cast<NSWindow*>(np_gl->window);
- new_window = reinterpret_cast<WindowRef>([ns_window windowRef]);
- } else {
- new_window = np_gl->window;
- }
- obj->mac_2d_context_ = NULL;
- obj->mac_cgl_context_ = np_gl->context;
- break;
+ case NPDrawingModelCoreAnimation: {
+ O3DLayer* o3dLayer = ObjO3DLayer(obj);
+ [o3dLayer setWidth: window->width height: window->height];
+ return NPERR_NO_ERROR;
}
case NPDrawingModelCoreGraphics: {
// Safari 4 sets window->window to NULL when in Cocoa event mode.
@@ -1001,8 +1059,10 @@ NPError NPP_SetWindow(NPP instance, NPWindow* window) {
obj->mac_window_ = new_window;
- if (obj->drawing_model_ == NPDrawingModelOpenGL) {
- CGLSetCurrentContext(obj->mac_cgl_context_);
+ if (obj->drawing_model_ == NPDrawingModelCoreAnimation) {
+ if (obj->mac_cgl_context_) {
+ CGLSetCurrentContext(obj->mac_cgl_context_);
+ }
} else if (obj->drawing_model_ == NPDrawingModelCoreGraphics &&
o3d::gIsChrome &&
obj->mac_cgl_pbuffer_ == NULL) {
@@ -1239,6 +1299,9 @@ NPError NPP_SetWindow(NPP instance, NPWindow* window) {
return NPERR_NO_ERROR;
}
+ if (obj->renderer())
+ return NPERR_NO_ERROR;
+
// Create and assign the graphics context.
o3d::DisplayWindowMac default_display;
default_display.set_agl_context(obj->mac_agl_context_);
diff --git a/o3d/plugin/mac/o3d_layer.h b/o3d/plugin/mac/o3d_layer.h
new file mode 100644
index 0000000..fc6872c
--- /dev/null
+++ b/o3d/plugin/mac/o3d_layer.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#import <Cocoa/Cocoa.h>
+#import <QuartzCore/QuartzCore.h>
+
+#import "plugin/cross/o3d_glue.h"
+
+using glue::_o3d::PluginObject;
+
+
+@interface O3DLayer : CAOpenGLLayer {
+ CGLContextObj glContext_;
+ PluginObject *obj_;
+ BOOL created_context_;
+ BOOL was_resized_;
+ int width_;
+ int height_;
+}
+
+- (CGLContextObj) glContext;
+
+- (void)drawInCGLContext:(CGLContextObj)ctx pixelFormat:(CGLPixelFormatObj)pf
+ forLayerTime:(CFTimeInterval)t displayTime:(const CVTimeStamp *)ts;
+
+- (void)setPluginObject:(PluginObject *)obj;
+
+- (void)setWidth:(int)width height:(int)height;
+
+
+@end
+
diff --git a/o3d/plugin/mac/o3d_layer.mm b/o3d/plugin/mac/o3d_layer.mm
new file mode 100644
index 0000000..9f43048
--- /dev/null
+++ b/o3d/plugin/mac/o3d_layer.mm
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#import "plugin_mac.h"
+#import <OpenGL/OpenGL.h>
+#import "o3d_layer.h"
+
+#include "display_window_mac.h"
+using o3d::DisplayWindowMac;
+
+@implementation O3DLayer
+
+
+- (id)init {
+ self = [super init];
+
+ // Set ourselves up to composite correctly. Users can write
+ // arbitrary alpha values into the back buffer but O3D's output is
+ // defined as being opaque. For correct rendering results we must
+ // basically drop the alpha channel while drawing to the screen
+ // using Core Animation. Setting the opaque flag achieves this.
+ if (self != nil) {
+ self.opaque = YES;
+ }
+
+ return self;
+}
+
+- (void)setPluginObject:(PluginObject *)obj {
+ obj_ = obj;
+}
+
+
+/* Called when a new frame needs to be generated for layer time 't'.
+ * 'ctx' is attached to the rendering destination. It's state is
+ * otherwise undefined. When non-null 'ts' describes the display
+ * timestamp associated with layer time 't'. The default implementation
+ * of the method flushes the context. */
+
+
+- (void)drawInCGLContext:(CGLContextObj)ctx
+ pixelFormat:(CGLPixelFormatObj)pf
+ forLayerTime:(CFTimeInterval)t
+ displayTime:(const CVTimeStamp *)ts {
+
+ // Set the current context to the one given to us.
+ CGLSetCurrentContext(ctx);
+
+ if (created_context_) {
+ DCHECK_EQ(ctx, obj_->mac_cgl_context_);
+ o3d::DisplayWindowMac default_display;
+ default_display.set_agl_context(obj_->mac_agl_context_);
+ default_display.set_cgl_context(obj_->mac_cgl_context_);
+ obj_->CreateRenderer(default_display);
+ obj_->client()->Init();
+ created_context_ = false;
+ }
+
+ if (was_resized_) {
+ obj_->Resize(width_, height_);
+ was_resized_ = false;
+ }
+
+
+ if (obj_) {
+ obj_->client()->Tick();
+ obj_->client()->RenderClient(true);
+ }
+
+ // Call super to finalize the drawing. By default it just calls glFlush().
+ [super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts];
+}
+
+- (BOOL)canDrawInCGLContext:(CGLContextObj)ctx
+ pixelFormat:(CGLPixelFormatObj)pf
+ forLayerTime:(CFTimeInterval)t
+ displayTime:(const CVTimeStamp *)ts {
+ return YES;
+}
+
+
+
+
+/* Called by the CAOpenGLLayer implementation when a rendering context
+ * is needed by the layer. Should return an OpenGL context with
+ * renderers from pixel format 'pixelFormat'. The default implementation
+ * allocates a new context with a null share context. */
+- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
+ glContext_ = [super copyCGLContextForPixelFormat:pixelFormat];
+ obj_->mac_cgl_context_ = glContext_;
+ created_context_ = true;
+
+ return glContext_;
+}
+
+/*
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
+ return [super copyCGLPixelFormatForDisplayMask:mask];
+}*/
+
+
+#define PFA(number) static_cast<CGLPixelFormatAttribute>(number)
+
+#define O3D_COLOR_AND_DEPTH_SETTINGS kCGLPFAClosestPolicy, \
+ kCGLPFAColorSize, PFA(24), \
+ kCGLPFAAlphaSize, PFA(8), \
+ kCGLPFADepthSize, PFA(24), \
+ kCGLPFADoubleBuffer,
+#define O3D_STENCIL_SETTINGS kCGLPFAStencilSize, PFA(8),
+#define O3D_HARDWARE_RENDERER kCGLPFAAccelerated, kCGLPFANoRecovery,
+#define O3D_MULTISAMPLE kCGLPFAMultisample, kCGLPFASamples, PFA(4),
+#define O3D_DISPLAY_MASK(mask) kCGLPFADisplayMask, PFA(mask),
+#define O3D_END PFA(0)
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
+ const CGLPixelFormatAttribute attributes[] = {
+ O3D_COLOR_AND_DEPTH_SETTINGS
+ O3D_STENCIL_SETTINGS
+ O3D_HARDWARE_RENDERER
+ O3D_DISPLAY_MASK(mask)
+ O3D_MULTISAMPLE
+ O3D_END
+ };
+ CGLPixelFormatObj pixel_format = NULL;
+ GLint num_screens = 0;
+ if (!CGLChoosePixelFormat(attributes, &pixel_format, &num_screens) &&
+ pixel_format) {
+ return pixel_format;
+ } else {
+ // Try a less capable set.
+ static const CGLPixelFormatAttribute low_end_attributes[] = {
+ O3D_COLOR_AND_DEPTH_SETTINGS
+ O3D_STENCIL_SETTINGS
+ O3D_HARDWARE_RENDERER
+ O3D_DISPLAY_MASK(mask)
+ O3D_END
+ };
+ if (!CGLChoosePixelFormat(low_end_attributes,
+ &pixel_format, &num_screens) && pixel_format) {
+ return pixel_format;
+ } else {
+ // Do whatever the superclass supports.
+ return [super copyCGLPixelFormatForDisplayMask:mask];
+ }
+ }
+}
+
+
+- (CGLContextObj)glContext {
+ return glContext_;
+}
+
+- (void)setWidth:(int)width height:(int)height {
+ width_ = width;
+ height_ = height;
+ was_resized_ = true;
+}
+
+@end
diff --git a/o3d/plugin/mac/plugin_mac.mm b/o3d/plugin/mac/plugin_mac.mm
index df25d9d..4ab3127 100644
--- a/o3d/plugin/mac/plugin_mac.mm
+++ b/o3d/plugin/mac/plugin_mac.mm
@@ -40,6 +40,8 @@
#include "plugin/cross/main.h"
#include "core/mac/display_window_mac.h"
#include "plugin/mac/graphics_utils_mac.h"
+#import "plugin/mac/o3d_layer.h"
+
#if !defined(O3D_INTERNAL_PLUGIN)
BreakpadRef gBreakpadRef = NULL;
@@ -236,6 +238,15 @@ void RenderTimer::TimerCallback(CFRunLoopTimerRef timer, void* info) {
NPP instance = instances_[i];
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+ if (obj->drawing_model_ == NPDrawingModelCoreAnimation) {
+ O3DLayer* o3dLayer = static_cast<O3DLayer*>(obj->gl_layer_);
+ if (o3dLayer) {
+ obj->client()->Tick();
+ [o3dLayer setNeedsDisplay];
+ }
+ return;
+ }
+
ManageSafariTabSwitching(obj);
obj->client()->Tick();
diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp
index fcb27b9..4bb27e2 100644
--- a/o3d/plugin/plugin.gyp
+++ b/o3d/plugin/plugin.gyp
@@ -150,6 +150,7 @@
],
'sources': [
'mac/config_mac.mm',
+ 'mac/o3d_layer.mm',
'mac/o3d_plugin.r',
'mac/plugin_logging-mac.mm',
'mac/plugin_mac.h',
@@ -168,6 +169,7 @@
],
'link_settings': {
'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
'$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
'$(SDKROOT)/System/Library/Frameworks/AGL.framework',