diff options
Diffstat (limited to 'o3d')
-rw-r--r-- | o3d/DEPS | 2 | ||||
-rw-r--r-- | o3d/build/cairo.gyp | 11 | ||||
-rw-r--r-- | o3d/build/common.gypi | 18 | ||||
-rw-r--r-- | o3d/build/libs.gyp | 76 | ||||
-rw-r--r-- | o3d/build/pixman.gyp | 4 | ||||
-rw-r--r-- | o3d/core/cross/cairo/renderer_cairo.cc | 95 | ||||
-rw-r--r-- | o3d/core/cross/cairo/renderer_cairo.h | 14 | ||||
-rw-r--r-- | o3d/core/cross/renderer.cc | 4 | ||||
-rw-r--r-- | o3d/core/cross/renderer.h | 15 | ||||
-rw-r--r-- | o3d/core/mac/display_window_mac.h | 15 | ||||
-rw-r--r-- | o3d/plugin/cross/o3d_glue.cc | 2 | ||||
-rw-r--r-- | o3d/plugin/cross/o3d_glue.h | 6 | ||||
-rw-r--r-- | o3d/plugin/mac/config_mac.mm | 4 | ||||
-rw-r--r-- | o3d/plugin/mac/main_mac.mm | 77 | ||||
-rw-r--r-- | o3d/plugin/mac/plugin_mac.mm | 16 |
15 files changed, 265 insertions, 94 deletions
@@ -7,7 +7,7 @@ vars = { "chromium_breakpad_rev": "47985", "o3d_code_rev": "232", "skia_rev": "586", - "gyp_rev": "820", + "gyp_rev": "899", "gtest_rev": "408", "gflags_rev": "30", "breakpad_rev": "604", diff --git a/o3d/build/cairo.gyp b/o3d/build/cairo.gyp index edeb6e4..2bcdf53 100644 --- a/o3d/build/cairo.gyp +++ b/o3d/build/cairo.gyp @@ -58,11 +58,12 @@ # Put our pkg-config binary into the PATH so cairo's build can # find it. 'PATH=<(pkgconfigroot)/usr/bin:$PATH && ' - # Configure it. We disable png and svg because we don't need - # them and they require additional external dependencies to - # build. - './configure --prefix=<(pkgconfigroot)/usr --disable-shared ' - '--disable-png --disable-svg && ' + # Configure it. + 'CFLAGS="-arch <(mac_gcc_arch)" ./configure ' + '--prefix=<(pkgconfigroot)/usr --disable-shared ' + # Disable things we don't need that have additional + # external dependencies. + '--disable-png --disable-svg --disable-ft && ' # Build. 'make && ' # "Install" to pkgconfigroot. diff --git a/o3d/build/common.gypi b/o3d/build/common.gypi index 2e848fd..796d493 100644 --- a/o3d/build/common.gypi +++ b/o3d/build/common.gypi @@ -51,7 +51,7 @@ 'cgdir': 'third_party/cg/files/mac', 'renderer%': 'gl', 'swiftshaderdir': '', - 'support_cairo%' : 0, + 'support_cairo%' : 1, }, ], ['OS == "linux"', @@ -189,6 +189,22 @@ ], ['OS == "mac"', { + 'conditions': [ + ['target_arch == "ia32"', + { + 'variables': { + 'mac_gcc_arch': 'i386', + }, + } + ], + ['target_arch == "x64"', + { + 'variables': { + 'mac_gcc_arch': 'x86_64', + }, + } + ], + ], 'target_defaults': { 'defines': [ 'OS_MACOSX', diff --git a/o3d/build/libs.gyp b/o3d/build/libs.gyp index 8a3f2f9..0f31c25 100644 --- a/o3d/build/libs.gyp +++ b/o3d/build/libs.gyp @@ -21,24 +21,54 @@ 'target_name': 'cairo_libs', 'type': 'none', 'conditions': [ - [ 'OS=="linux"', + ['OS=="linux"', { 'all_dependent_settings': { 'cflags': [ '<!@(pkg-config --cflags cairo)', ], + 'ldflags': [ + '<!@(pkg-config --libs-only-L --libs-only-other cairo)', + ], 'libraries': [ - '-lcairo', + '<!@(pkg-config --libs-only-l cairo)', ], }, }, ], - [ 'OS=="mac"', + ['OS=="mac"', { - #TODO(fransiskusx): Link to Cairo on Win/Mac as a static library + 'dependencies': [ + 'pixman.gyp:pixman', + 'cairo.gyp:cairo', + ], + # Ideally we would just call our pkg-config build here to query the + # right settings, but there are multiple problems with GYP/Xcode + # that prevent that from working, so we hard-code the values. + 'all_dependent_settings': { + 'include_dirs': [ + '<(pkgconfigroot)/usr/include/cairo', + '<(pkgconfigroot)/usr/include/pixman-1', + ], + # GYP/Xcode also has problems with adding libraries to all + # dependents, so we have to put them in this target_conditions + # section to restrict them to just the target types that we care + # about. + 'target_conditions': [ + ['_type=="executable" or _type=="shared_library" ' + 'or _type=="loadable_module"', + { + 'libraries': [ + '<(pkgconfigroot)/usr/lib/libcairo.a', + '<(pkgconfigroot)/usr/lib/libpixman-1.a', + ] + }, + ], + ], + }, }, ], - [ 'OS=="win"', + ['OS=="win"', { 'all_dependent_settings': { 'defines': [ @@ -66,14 +96,14 @@ ], }, 'conditions': [ - [ 'OS=="linux"', + ['OS=="linux"', { 'all_dependent_settings': { 'defines': [ 'GL_GLEXT_PROTOTYPES', ], 'conditions': [ - [ 'target_arch=="x64"', + ['target_arch=="x64"', { 'variables': { 'libdir': 'lib64' } }, { @@ -93,7 +123,7 @@ }, }, ], - [ 'OS=="mac"', + ['OS=="mac"', { 'direct_dependent_settings': { 'libraries': [ @@ -102,7 +132,7 @@ }, }, ], - [ 'OS=="win"', + ['OS=="win"', { 'all_dependent_settings': { 'libraries': [ @@ -134,14 +164,14 @@ ], }, 'conditions': [ - [ 'OS=="linux"', + ['OS=="linux"', { 'all_dependent_settings': { 'defines': [ 'GL_GLEXT_PROTOTYPES', ], 'conditions': [ - [ 'target_arch=="x64"', + ['target_arch=="x64"', { 'variables': { 'libdir': 'lib64' } }, { @@ -161,7 +191,7 @@ }, }, ], - [ 'OS=="mac"', + ['OS=="mac"', { 'direct_dependent_settings': { 'libraries': [ @@ -170,7 +200,7 @@ }, }, ], - [ 'OS=="win"', + ['OS=="win"', { 'all_dependent_settings': { 'libraries': [ @@ -217,7 +247,7 @@ ], }, 'conditions': [ - [ 'OS=="linux"', + ['OS=="linux"', { 'all_dependent_settings': { 'ldflags': [ @@ -230,7 +260,7 @@ }, }, ], - [ 'OS=="win"', + ['OS=="win"', { 'all_dependent_settings': { 'libraries': [ @@ -242,7 +272,7 @@ }, }, ], - [ 'OS=="mac"', + ['OS=="mac"', { 'direct_dependent_settings': { 'mac_framework_dirs': [ @@ -258,11 +288,11 @@ 'copies': [ { 'conditions' : [ - [ 'OS=="linux"', + ['OS=="linux"', { 'destination': '<(PRODUCT_DIR)', 'conditions': [ - [ 'target_arch=="x64"', + ['target_arch=="x64"', { 'variables': { 'libdir': 'lib64' } }, { @@ -277,7 +307,7 @@ ], }, ], - [ 'OS=="win"', + ['OS=="win"', { 'destination': '<(PRODUCT_DIR)', 'files': [ @@ -289,7 +319,7 @@ ], }, ], - [ 'OS=="mac"', + ['OS=="mac"', { 'destination': '<(PRODUCT_DIR)/Library/Frameworks', 'files': [ @@ -301,7 +331,7 @@ }, { 'conditions' : [ - [ 'OS=="linux"', + ['OS=="linux"', { 'destination': '<(SHARED_LIB_DIR)', 'files': [ @@ -310,7 +340,7 @@ ], }, ], - [ 'OS=="mac"', + ['OS=="mac"', { # Dummy copy, because the xcode generator in gyp fails when it # has an empty copy entry. @@ -365,7 +395,7 @@ ], }, ], - } + }, ], ], } diff --git a/o3d/build/pixman.gyp b/o3d/build/pixman.gyp index ae4278f..a6e9457 100644 --- a/o3d/build/pixman.gyp +++ b/o3d/build/pixman.gyp @@ -38,8 +38,8 @@ # Go there! 'cd <(pixmanbuilddir) && ' # Configure it. - './configure --prefix=<(pkgconfigroot)/usr --disable-shared ' - '&& ' + 'CFLAGS="-arch <(mac_gcc_arch)" ./configure ' + '--prefix=<(pkgconfigroot)/usr --disable-shared && ' # Build. 'make && ' # "Install" to pkgconfigroot. diff --git a/o3d/core/cross/cairo/renderer_cairo.cc b/o3d/core/cross/cairo/renderer_cairo.cc index 885d477..66e1c83 100644 --- a/o3d/core/cross/cairo/renderer_cairo.cc +++ b/o3d/core/cross/cairo/renderer_cairo.cc @@ -32,10 +32,16 @@ // Renderer that is using 2D Library Cairo. #include "core/cross/cairo/renderer_cairo.h" + +#if defined(OS_LINUX) #include <cairo-xlib.h> +#elif defined(OS_MACOSX) +#include <cairo-quartz.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "core/cross/cairo/layer.h" #include "core/cross/cairo/texture_cairo.h" @@ -49,7 +55,14 @@ Renderer* Renderer::Create2DRenderer(ServiceLocator* service_locator) { namespace o2d { RendererCairo::RendererCairo(ServiceLocator* service_locator) - : Renderer(service_locator), display_(NULL), main_surface_(NULL) { + : Renderer(service_locator), +#if defined(OS_LINUX) + display_(NULL), + window_(0), +#elif defined(OS_MACOSX) + mac_cg_context_ref_(0), +#endif + main_surface_(NULL) { // Don't need to do anything. } @@ -65,12 +78,14 @@ RendererCairo* RendererCairo::CreateDefault(ServiceLocator* service_locator) { void RendererCairo::Destroy() { DLOG(INFO) << "To Destroy"; - if (main_surface_ != NULL) { - cairo_surface_destroy(main_surface_); - main_surface_= NULL; - } + DestroyCairoSurface(); +#if defined(OS_LINUX) display_ = NULL; + window_ = 0; +#elif defined(OS_MACOSX) + mac_cg_context_ref_ = 0; +#endif } // Comparison predicate for STL sort. @@ -79,6 +94,11 @@ bool LayerZValueLessThan(const Layer* first, const Layer* second) { } void RendererCairo::Paint() { + if (!main_surface_) { + DLOG(INFO) << "No target surface, cannot paint"; + return; + } + // TODO(tschmelcher): Don't keep creating and destroying the drawing context. cairo_t* current_drawing = cairo_create(main_surface_); @@ -201,9 +221,48 @@ void RendererCairo::RemoveLayer(Layer* image) { } void RendererCairo::InitCommon() { - main_surface_ = cairo_xlib_surface_create(display_, window_, + CreateCairoSurface(); +} + +void RendererCairo::CreateCairoSurface() { +#if defined(OS_LINUX) + main_surface_ = cairo_xlib_surface_create(display_, + window_, XDefaultVisual(display_, 0), - display_width(), display_height()); + display_width(), + display_height()); +#elif defined(OS_MACOSX) + if (!mac_cg_context_ref_) { + // Can't create the surface until we get a valid CGContextRef. If we don't + // have one it may be because we haven't yet gotten one from + // HandleCocoaEvent() in main_mac.mm, or we may have initialized with a + // drawing model other than Core Graphics (in which case we are never going + // to get one and rendering won't work). + // TODO(tschmelcher): Support the other drawing models too. + DLOG(INFO) << "No CGContextRef, cannot initialize yet"; + return; + } + // Save a pristine CG graphics state. + CGContextSaveGState(mac_cg_context_ref_); + // Transform the coordinate space to match Cairo's conventions. + CGContextTranslateCTM(mac_cg_context_ref_, 0.0, display_height()); + CGContextScaleCTM(mac_cg_context_ref_, 1.0, -1.0); + main_surface_ = cairo_quartz_surface_create_for_cg_context( + mac_cg_context_ref_, + display_width(), + display_height()); +#endif +} + +void RendererCairo::DestroyCairoSurface() { + if (main_surface_ != NULL) { + cairo_surface_destroy(main_surface_); + main_surface_= NULL; +#ifdef OS_MACOSX + // Get back the pristine CG state. + CGContextRestoreGState(mac_cg_context_ref_); +#endif + } } void RendererCairo::UninitCommon() { @@ -213,21 +272,41 @@ void RendererCairo::UninitCommon() { Renderer::InitStatus RendererCairo::InitPlatformSpecific( const DisplayWindow& display_window, bool off_screen) { +#if defined(OS_LINUX) const DisplayWindowLinux &display_platform = static_cast<const DisplayWindowLinux&>(display_window); display_ = display_platform.display(); window_ = display_platform.window(); - +#elif defined(OS_MACOSX) + const DisplayWindowMac &display_platform = + static_cast<const DisplayWindowMac&>(display_window); + mac_cg_context_ref_ = display_platform.cg_context_ref(); +#endif return SUCCESS; } +#ifdef OS_MACOSX +bool RendererCairo::ChangeDisplayWindow(const DisplayWindow& display_window) { + const DisplayWindowMac &display_platform = + static_cast<const DisplayWindowMac&>(display_window); + DestroyCairoSurface(); + mac_cg_context_ref_ = display_platform.cg_context_ref(); + CreateCairoSurface(); +} +#endif + // Handles the plugin resize event. void RendererCairo::Resize(int width, int height) { DLOG(INFO) << "To Resize " << width << " x " << height; SetClientSize(width, height); +#if defined(OS_LINUX) // Resize the mainSurface and buffer cairo_xlib_surface_set_size(main_surface_, width, height); +#elif defined(OS_MACOSX) + DestroyCairoSurface(); + CreateCairoSurface(); +#endif } // The platform specific part of BeginDraw. diff --git a/o3d/core/cross/cairo/renderer_cairo.h b/o3d/core/cross/cairo/renderer_cairo.h index d3c8e94..b80d246 100644 --- a/o3d/core/cross/cairo/renderer_cairo.h +++ b/o3d/core/cross/cairo/renderer_cairo.h @@ -62,6 +62,12 @@ class RendererCairo : public Renderer { virtual InitStatus InitPlatformSpecific(const DisplayWindow& display, bool off_screen); +#ifdef OS_MACOSX + virtual bool ChangeDisplayWindow(const DisplayWindow& display); + + virtual bool SupportsCoreGraphics() const { return true; } +#endif + // Released all hardware resources. virtual void Destroy(); @@ -221,10 +227,18 @@ class RendererCairo : public Renderer { // Clip the area of the current layer that will collide with other images. void ClipArea(cairo_t* cr, LayerList::iterator it); + private: + void CreateCairoSurface(); + void DestroyCairoSurface(); + +#if defined(OS_LINUX) // Linux Client Display Display* display_; // Linux Client Window Window window_; +#elif defined(OS_MACOSX) + CGContextRef mac_cg_context_ref_; +#endif // Main surface to render cairo cairo_surface_t* main_surface_; diff --git a/o3d/core/cross/renderer.cc b/o3d/core/cross/renderer.cc index 3a71722..a1d50f1 100644 --- a/o3d/core/cross/renderer.cc +++ b/o3d/core/cross/renderer.cc @@ -150,6 +150,10 @@ Renderer::InitStatus Renderer::Init( return InitPlatformSpecific(display, off_screen); } +bool Renderer::ChangeDisplayWindow(const DisplayWindow& display) { + return false; +} + void Renderer::InitCommon() { AddDefaultStates(); SetInitialStates(); diff --git a/o3d/core/cross/renderer.h b/o3d/core/cross/renderer.h index 311fb6d..f198570 100644 --- a/o3d/core/cross/renderer.h +++ b/o3d/core/cross/renderer.h @@ -158,7 +158,6 @@ class Renderer { // needed by the application. static Renderer* Create2DRenderer(ServiceLocator* service_locator); - // Gets whether or not the renderer should attempt to use the software // renderer. static bool IsForceSoftwareRenderer(); @@ -166,9 +165,9 @@ class Renderer { // Initialises the renderer for use, claiming hardware resources. InitStatus Init(const DisplayWindow& display, bool off_screen); - // The platform specific part of initalization. - virtual InitStatus InitPlatformSpecific(const DisplayWindow& display, - bool off_screen) = 0; + // Switch rendering to a different window after initialization (if supported + // by the implementation). + virtual bool ChangeDisplayWindow(const DisplayWindow& display); // Initializes stuff that has to happen after Init virtual void InitCommon(); @@ -406,6 +405,10 @@ class Renderer { int width, int height) = 0; +#ifdef OS_MACOSX + virtual bool SupportsCoreGraphics() const { return false; } +#endif + ServiceLocator* service_locator() const { return service_locator_; } // Returns the type of Param needed for a particular state. @@ -677,6 +680,10 @@ class Renderer { } private: + // The platform specific part of initalization. + virtual InitStatus InitPlatformSpecific(const DisplayWindow& display, + bool off_screen) = 0; + // Adds the default states to their respective stacks. void AddDefaultStates(); diff --git a/o3d/core/mac/display_window_mac.h b/o3d/core/mac/display_window_mac.h index 29eeec6..6390617 100644 --- a/o3d/core/mac/display_window_mac.h +++ b/o3d/core/mac/display_window_mac.h @@ -35,6 +35,7 @@ #include <OpenGL/OpenGL.h> #include <AGL/agl.h> +#include <CoreGraphics/CGContext.h> #include "core/cross/display_window.h" @@ -48,11 +49,17 @@ namespace o3d { class DisplayWindowMac : public DisplayWindow { public: - DisplayWindowMac() : agl_context_(NULL), cgl_context_(NULL) {} + DisplayWindowMac() + : agl_context_(NULL), + cgl_context_(NULL), + cg_context_ref_(NULL) { + } + virtual ~DisplayWindowMac() {} AGLContext agl_context() const { return agl_context_; } CGLContextObj cgl_context() const { return cgl_context_; } + CGContextRef cg_context_ref() const { return cg_context_ref_; } void set_agl_context(const AGLContext& agl_context) { agl_context_ = agl_context; @@ -61,9 +68,15 @@ class DisplayWindowMac : public DisplayWindow { void set_cgl_context(const CGLContextObj& cgl_context) { cgl_context_ = cgl_context; } + + void set_cg_context_ref(const CGContextRef& cg_context_ref) { + cg_context_ref_ = cg_context_ref; + } + private: AGLContext agl_context_; CGLContextObj cgl_context_; + CGContextRef cg_context_ref_; DISALLOW_COPY_AND_ASSIGN(DisplayWindowMac); }; diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc index d3da84d..ea64a84 100644 --- a/o3d/plugin/cross/o3d_glue.cc +++ b/o3d/plugin/cross/o3d_glue.cc @@ -133,7 +133,7 @@ PluginObject::PluginObject(NPP npp) mac_window_selected_tab_(0), mac_cocoa_window_(0), mac_surface_hidden_(0), - mac_2d_context_(0), + mac_cg_context_ref_(0), mac_agl_context_(0), mac_cgl_context_(0), mac_cgl_pbuffer_(0), diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h index 9af13dd..213687b 100644 --- a/o3d/plugin/cross/o3d_glue.h +++ b/o3d/plugin/cross/o3d_glue.h @@ -38,6 +38,7 @@ #ifdef OS_MACOSX #include <OpenGL/OpenGL.h> #include <AGL/agl.h> +#include <CoreGraphics/CGContext.h> #endif #ifdef OS_LINUX @@ -285,9 +286,8 @@ class PluginObject: public NPObject { // end of Safari tab detection vars GLint last_buffer_rect_[4]; Point last_plugin_loc_; - // can be a CGrafPtr, a CGContextRef or NULL depending on drawing_model - void* mac_2d_context_; - // either can be NULL depending on drawing_model + // each of these three can be NULL depending on drawing_model + CGContextRef mac_cg_context_ref_; AGLContext mac_agl_context_; CGLContextObj mac_cgl_context_; void *gl_layer_; diff --git a/o3d/plugin/mac/config_mac.mm b/o3d/plugin/mac/config_mac.mm index c85f8c8..df5673c 100644 --- a/o3d/plugin/mac/config_mac.mm +++ b/o3d/plugin/mac/config_mac.mm @@ -330,10 +330,10 @@ bool GetUserAgentMetrics(NPP npp) { // The Chrome user_agent string also contains Safari. Search for Chrome first. if (std::string::npos != user_agent.find("Chrome")) { o3d::metric_browser_type = o3d::BROWSER_NAME_CHROME; - // The OmniWeb user_agent also contains Safari. Search for OminWeb first. + // The OmniWeb user_agent also contains Safari. Search for OmniWeb first. } else if (std::string::npos != user_agent.find("OmniWeb")) { o3d::metric_browser_type = o3d::BROWSER_NAME_OMNIWEB; - // now we can safely look for Safari + // Now we can safely look for Safari. } else if (std::string::npos != user_agent.find("Safari")) { o3d::metric_browser_type = o3d::BROWSER_NAME_SAFARI; } else if (std::string::npos != user_agent.find("Opera")) { diff --git a/o3d/plugin/mac/main_mac.mm b/o3d/plugin/mac/main_mac.mm index e3daf86..d06d305 100644 --- a/o3d/plugin/mac/main_mac.mm +++ b/o3d/plugin/mac/main_mac.mm @@ -691,9 +691,7 @@ bool HandleMacEvent(EventRecord* the_event, NPP instance) { GLUE_PROFILE_STOP(instance, "forceredraw"); #elif defined(CFTIMER) #else - DrawPlugin(obj, true, - (obj->drawing_model_ == NPDrawingModelCoreGraphics) ? - reinterpret_cast<CGContextRef>(obj->mac_2d_context_) : NULL); + DrawPlugin(obj, true, obj->mac_cg_context_ref_); #endif // Safari tab switching recovery code. if (obj->mac_surface_hidden_) { @@ -718,9 +716,7 @@ bool HandleMacEvent(EventRecord* the_event, NPP instance) { handled = true; break; case updateEvt: - DrawPlugin(obj, false, - (obj->drawing_model_ == NPDrawingModelCoreGraphics) ? - reinterpret_cast<CGContextRef>(obj->mac_2d_context_) : NULL); + DrawPlugin(obj, false, obj->mac_cg_context_ref_); handled = true; break; case osEvt: @@ -780,17 +776,26 @@ bool HandleCocoaEvent(NPP instance, NPCocoaEvent* the_event, obj->MacEventReceived(!lostFocus); switch (the_event->type) { 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. if (obj->drawing_model_ == NPDrawingModelCoreAnimation) { O3DLayer* layer = ObjO3DLayer(obj); if (layer) { [layer setNeedsDisplay]; } } else { - DrawPlugin(obj, - obj->IsOffscreenRenderingEnabled(), - the_event->data.draw.context); + // We need to call the render callback from here if we are using + // Core Graphics because it doesn't get called anywhere else. + CGContextRef new_mac_cg_context_ref = the_event->data.draw.context; + if (new_mac_cg_context_ref != obj->mac_cg_context_ref_) { + obj->mac_cg_context_ref_ = new_mac_cg_context_ref; + // Update the Renderer's CGContextRef (only RendererCairo actually + // uses it). + o3d::DisplayWindowMac display; + display.set_agl_context(obj->mac_agl_context_); + display.set_cgl_context(obj->mac_cgl_context_); + display.set_cg_context_ref(obj->mac_cg_context_ref_); + obj->renderer()->ChangeDisplayWindow(display); + } + DrawPlugin(obj, true, obj->mac_cg_context_ref_); } handled = true; break; @@ -931,7 +936,7 @@ NPError PlatformNPPSetWindow(NPP instance, if (window->window == NULL && obj->drawing_model_ != NPDrawingModelCoreGraphics && - obj->drawing_model_!= NPDrawingModelCoreAnimation) { + obj->drawing_model_ != NPDrawingModelCoreAnimation) { return NPERR_NO_ERROR; } @@ -945,7 +950,9 @@ NPError PlatformNPPSetWindow(NPP instance, return NPERR_NO_ERROR; } case NPDrawingModelCoreGraphics: { - // Safari 4 sets window->window to NULL when in Cocoa event mode. + // In some browsers (Safari 4 on 10.5, Chrome on 10.5), window->window is + // NULL when using the Cocoa event model. In that situation we get our + // CGContextRef in HandleCocoaEvent() instead. if (window->window != NULL) { NP_CGContext* np_cg = reinterpret_cast<NP_CGContext*>(window->window); if (obj->event_model_ == NPEventModelCocoa) { @@ -954,13 +961,12 @@ NPError PlatformNPPSetWindow(NPP instance, } else { new_window = static_cast<OpaqueWindowPtr*>(np_cg->window); } - obj->mac_2d_context_ = np_cg->context; + obj->mac_cg_context_ref_ = np_cg->context; } break; } case NPDrawingModelQuickDraw: { NP_Port* np_qd = reinterpret_cast<NP_Port*>(window->window); - obj->mac_2d_context_ = np_qd->port; if (np_qd->port) new_window = GetWindowFromPort(np_qd->port); // Safari 4 on Snow Leopard is sending us a spurious @@ -982,9 +988,6 @@ NPError PlatformNPPSetWindow(NPP instance, // Whether we already had a window before this call. bool had_a_window = obj->mac_window_ != NULL; - // Whether we already had a pbuffer before this call. - bool had_a_pbuffer = obj->mac_cgl_pbuffer_ != NULL; - obj->mac_window_ = new_window; if (obj->drawing_model_ == NPDrawingModelCoreAnimation) { @@ -992,6 +995,8 @@ NPError PlatformNPPSetWindow(NPP instance, CGLSetCurrentContext(obj->mac_cgl_context_); } } else if (obj->drawing_model_ == NPDrawingModelCoreGraphics) { + // TODO(tschmelcher): We could skip this when RenderMode is 2D (though it's + // harmless). if (obj->mac_cgl_pbuffer_ == NULL) { // We initialize things with a CGL context rendering to a 1x1 // pbuffer. Later we use the O3D RenderSurface APIs to set up the @@ -1195,31 +1200,28 @@ NPError PlatformNPPSetWindow(NPP instance, aglEnable(obj->mac_agl_context_, AGL_BUFFER_RECT); } - if (had_a_pbuffer) { - // CoreGraphics drawing model when we have no on-screen window (Chrome, - // specifically). - obj->EnableOffscreenRendering(); - obj->Resize(window->width, window->height); - return NPERR_NO_ERROR; - } - - // Renderer is already initialized from a previous call to this function, - // just update size and position and return. - if (had_a_window) { - if (obj->renderer()) { + if (obj->renderer()) { + // Renderer is already initialized from a previous call to this function, + // just update size and position and return. + if (obj->drawing_model_ == NPDrawingModelCoreGraphics) { + if (!obj->renderer()->SupportsCoreGraphics()) { + obj->EnableOffscreenRendering(); + } + obj->Resize(window->width, window->height); + } else if (had_a_window) { obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); obj->Resize(window->width, window->height); } return NPERR_NO_ERROR; } - if (obj->renderer()) - return NPERR_NO_ERROR; + // Else this is the first call. // Create and assign the graphics context. o3d::DisplayWindowMac default_display; default_display.set_agl_context(obj->mac_agl_context_); default_display.set_cgl_context(obj->mac_cgl_context_); + default_display.set_cg_context_ref(obj->mac_cg_context_ref_); obj->CreateRenderer(default_display); @@ -1235,15 +1237,20 @@ NPError PlatformNPPSetWindow(NPP instance, obj->client()->Init(); if (obj->renderer()) { - if (obj->mac_cgl_pbuffer_) { - obj->EnableOffscreenRendering(); + if (obj->drawing_model_ == NPDrawingModelCoreGraphics) { + if (!obj->renderer()->SupportsCoreGraphics()) { + // Browser is using Core Graphics but renderer doesn't support it, so we + // must render off-screen and then read back into software to re-render + // with Core Graphics. + obj->EnableOffscreenRendering(); + } } else { obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); } obj->Resize(window->width, window->height); #ifdef CFTIMER - // now that the grahics context is setup, add this instance to the timer + // now that the graphics context is setup, add this instance to the timer // list so it gets drawn repeatedly gRenderTimer.AddInstance(instance); #endif // CFTIMER diff --git a/o3d/plugin/mac/plugin_mac.mm b/o3d/plugin/mac/plugin_mac.mm index 9fb57a5..199a061 100644 --- a/o3d/plugin/mac/plugin_mac.mm +++ b/o3d/plugin/mac/plugin_mac.mm @@ -270,22 +270,22 @@ void RenderTimer::TimerCallback(CFRunLoopTimerRef timer, void* info) { obj->GetFullscreenMacWindow()->IdleCallback(); } - // We're visible if (a) we are in fullscreen mode, (b) our cliprect - // height and width are both a sensible size, ie > 1 pixel, or (c) if - // we are rendering to render surfaces (CoreGraphics drawing model, - // essentially offscreen rendering). + // We're visible if (a) we are in fullscreen mode, (b) we are using + // QuickDraw and our cliprect height and width are both a sensible size, ie + // > 1 pixel, or (c) we are using Core Graphics. // // We don't check for 0 as we have to size to 1 x 1 on occasion rather than // 0 x 0 to avoid crashing the Apple software renderer, but do not want to // actually draw to a 1 x 1 pixel area. bool plugin_visible = in_fullscreen || - (obj->last_buffer_rect_[2] > 1 && obj->last_buffer_rect_[3] > 1) || - obj->IsOffscreenRenderingEnabled(); + (obj->drawing_model_ == NPDrawingModelQuickDraw && + obj->last_buffer_rect_[2] > 1 && obj->last_buffer_rect_[3] > 1) || + obj->drawing_model_ == NPDrawingModelCoreGraphics; if (plugin_visible && obj->renderer()) { if (obj->client()->NeedsRender()) { // Force a sync to the VBL (once per timer callback) - // to avoid tearing + // to avoid tearing, if using GL. GLint sync = (i == 0); if (obj->mac_cgl_context_) { CGLSetParameter(obj->mac_cgl_context_, kCGLCPSwapInterval, &sync); @@ -293,7 +293,7 @@ void RenderTimer::TimerCallback(CFRunLoopTimerRef timer, void* info) { aglSetInteger(obj->mac_agl_context_, AGL_SWAP_INTERVAL, &sync); } - if (obj->IsOffscreenRenderingEnabled()) { + if (obj->drawing_model_ == NPDrawingModelCoreGraphics) { NPRect rect = { 0 }; rect.bottom = obj->height(); rect.right = obj->width(); |