summaryrefslogtreecommitdiffstats
path: root/o3d/plugin/cross/o3d_glue.cc
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/plugin/cross/o3d_glue.cc')
-rw-r--r--o3d/plugin/cross/o3d_glue.cc104
1 files changed, 103 insertions, 1 deletions
diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc
index 6a2d53f..0d66e9c 100644
--- a/o3d/plugin/cross/o3d_glue.cc
+++ b/o3d/plugin/cross/o3d_glue.cc
@@ -37,7 +37,9 @@
#include <string>
#include <algorithm>
+#include "core/cross/image_utils.h"
#include "core/cross/renderer.h"
+#include "core/cross/texture.h"
#include "core/cross/client_info.h"
#include "plugin/cross/o3d_glue.h"
#include "plugin/cross/config.h"
@@ -56,6 +58,10 @@
namespace glue {
namespace _o3d {
+using o3d::Bitmap;
+using o3d::Texture;
+using o3d::Texture2D;
+
void RegisterType(NPP npp, const ObjectBase::Class *clientclass,
NPClass *npclass) {
PluginObject *plugin_object = static_cast<PluginObject *>(npp->pdata);
@@ -134,6 +140,7 @@ PluginObject::PluginObject(NPP npp)
mac_2d_context_(0),
mac_agl_context_(0),
mac_cgl_context_(0),
+ mac_cgl_pbuffer_(0),
last_mac_event_time_(0),
#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG
time_to_hide_overlay_(0.0),
@@ -165,7 +172,8 @@ PluginObject::PluginObject(NPP npp)
stream_manager_(new StreamManager(npp)),
cursor_type_(o3d::Cursor::DEFAULT),
prev_width_(0),
- prev_height_(0) {
+ prev_height_(0),
+ offscreen_rendering_enabled_(false) {
#if defined(OS_WIN) || defined(OS_LINUX)
memset(cursors_, 0, sizeof(cursors_));
#endif
@@ -218,6 +226,7 @@ void PluginObject::Init(int argc, char* argn[], char* argv[]) {
}
void PluginObject::TearDown() {
+ DisableOffscreenRendering();
#ifdef OS_WIN
ClearPluginProperty(hWnd_);
#elif defined(OS_MACOSX)
@@ -717,6 +726,12 @@ void PluginObject::Resize(int width, int height) {
prev_height_ = height;
if (renderer_ && !fullscreen_) {
+ // If we are rendering offscreen, we may need to reallocate the
+ // render surfaces.
+ if (offscreen_rendering_enabled_) {
+ AllocateOffscreenRenderSurfaces(width, height);
+ }
+
// Tell the renderer and client that our window has been resized.
// If we're in fullscreen mode when this happens, we don't want to pass
// the information through; the renderer will pick it up when we switch
@@ -1053,6 +1068,93 @@ void PluginObject::Tick() {
}
}
+void PluginObject::EnableOffscreenRendering() {
+ if (!offscreen_rendering_enabled_) {
+ AllocateOffscreenRenderSurfaces(width(), height());
+ offscreen_rendering_enabled_ = true;
+ }
+}
+
+void PluginObject::DisableOffscreenRendering() {
+ if (offscreen_rendering_enabled_) {
+ DeallocateOffscreenRenderSurfaces();
+ offscreen_rendering_enabled_ = false;
+ }
+}
+
+bool PluginObject::IsOffscreenRenderingEnabled() const {
+ return offscreen_rendering_enabled_;
+}
+
+RenderSurface::Ref PluginObject::GetOffscreenRenderSurface() const {
+ return offscreen_render_surface_;
+}
+
+Bitmap::Ref PluginObject::GetOffscreenBitmap() const {
+ return offscreen_readback_bitmap_;
+}
+
+bool PluginObject::AllocateOffscreenRenderSurfaces(int width, int height) {
+ int pot_width =
+ static_cast<int>(o3d::image::ComputePOTSize(width));
+ int pot_height =
+ static_cast<int>(o3d::image::ComputePOTSize(height));
+ if (!renderer_ || pot_width == 0 || pot_height == 0) {
+ return false;
+ }
+ bool must_reallocate_render_surfaces =
+ (offscreen_render_surface_.IsNull() ||
+ offscreen_depth_render_surface_.IsNull() ||
+ offscreen_render_surface_->width() != pot_width ||
+ offscreen_render_surface_->height() != pot_height);
+ if (must_reallocate_render_surfaces) {
+ Texture2D::Ref texture = renderer_->CreateTexture2D(
+ pot_width,
+ pot_height,
+ Texture::ARGB8,
+ 1,
+ true);
+ if (texture.IsNull()) {
+ return false;
+ }
+ RenderSurface::Ref surface(texture->GetRenderSurface(0));
+ if (surface.IsNull()) {
+ return false;
+ }
+ RenderDepthStencilSurface::Ref depth(renderer_->CreateDepthStencilSurface(
+ pot_width,
+ pot_height));
+ if (depth.IsNull()) {
+ return false;
+ }
+ offscreen_texture_ = texture;
+ offscreen_render_surface_ = surface;
+ offscreen_depth_render_surface_ = depth;
+ }
+ offscreen_render_surface_->SetClipSize(width, height);
+ offscreen_depth_render_surface_->SetClipSize(width, height);
+ if (offscreen_readback_bitmap_.IsNull() ||
+ offscreen_readback_bitmap_->width() != width ||
+ offscreen_readback_bitmap_->height() != height) {
+ o3d::Bitmap::Ref bitmap = Bitmap::Ref(
+ new Bitmap(service_locator()));
+ bitmap->Allocate(Texture::ARGB8,
+ width, height, 1, Bitmap::IMAGE);
+ offscreen_readback_bitmap_ = bitmap;
+ }
+ // Tell the Client about the newly allocated surfaces so that normal
+ // calls to RenderClient can automatically do the right thing.
+ client_->SetOffscreenRenderingSurfaces(offscreen_render_surface_,
+ offscreen_depth_render_surface_);
+ return true;
+}
+
+void PluginObject::DeallocateOffscreenRenderSurfaces() {
+ offscreen_render_surface_.Reset();
+ offscreen_depth_render_surface_.Reset();
+ offscreen_readback_bitmap_.Reset();
+}
+
} // namespace _o3d
namespace globals {