| Index: plugin/mac/main_mac.mm
|
| ===================================================================
|
| --- plugin/mac/main_mac.mm (revision 44394)
|
| +++ plugin/mac/main_mac.mm (working copy)
|
| @@ -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,7 +56,9 @@
|
| #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;
|
| bool g_logging_initialized = false;
|
| @@ -80,6 +83,15 @@
|
| #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 @@
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| } // 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 @@
|
|
|
| #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 @@
|
| 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 @@
|
| 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 @@
|
|
|
| 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 @@
|
| 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_);
|
|
|