summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
Diffstat (limited to 'o3d')
-rw-r--r--o3d/DEPS2
-rw-r--r--o3d/build/cairo.gyp11
-rw-r--r--o3d/build/common.gypi18
-rw-r--r--o3d/build/libs.gyp76
-rw-r--r--o3d/build/pixman.gyp4
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.cc95
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.h14
-rw-r--r--o3d/core/cross/renderer.cc4
-rw-r--r--o3d/core/cross/renderer.h15
-rw-r--r--o3d/core/mac/display_window_mac.h15
-rw-r--r--o3d/plugin/cross/o3d_glue.cc2
-rw-r--r--o3d/plugin/cross/o3d_glue.h6
-rw-r--r--o3d/plugin/mac/config_mac.mm4
-rw-r--r--o3d/plugin/mac/main_mac.mm77
-rw-r--r--o3d/plugin/mac/plugin_mac.mm16
15 files changed, 265 insertions, 94 deletions
diff --git a/o3d/DEPS b/o3d/DEPS
index 61c3fc3..eb8c70f 100644
--- a/o3d/DEPS
+++ b/o3d/DEPS
@@ -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();