summaryrefslogtreecommitdiffstats
path: root/o3d/core
diff options
context:
space:
mode:
authorgman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-25 00:18:47 +0000
committergman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-25 00:18:47 +0000
commit2976fe30ed9e0454b0995456e64a5ef7ae216df8 (patch)
tree5194cf65778a90b5a277df3d635b8164da39bb50 /o3d/core
parentc874da66d375909e04eb2a0aba669b162c41faba (diff)
downloadchromium_src-2976fe30ed9e0454b0995456e64a5ef7ae216df8.zip
chromium_src-2976fe30ed9e0454b0995456e64a5ef7ae216df8.tar.gz
chromium_src-2976fe30ed9e0454b0995456e64a5ef7ae216df8.tar.bz2
Cleanup Renderer.
I believe there were some mis-understandings about the code. It's supposed to work StartRendering(); BeginDraw(); EndDraw(); BeginDraw(); EndDraw(); BeginDraw(); EndDraw(); FinishRendering(); To try to enforce correct usage I separated some platform dependant stuff from shared stuff and added a few flags. Also in this CL I made Texture::GetRenderSurface not require a pack. This is so I because it feels cleaner that way but also because I wanted to use surfaces without a pack to take a screenshot. Finally I put some screenshot code in for GL. Also fixed some bugs with locking textures. 1) I thought it was x, y, width, height but it's actually x1, y1, x2, y2 2) I was using width in places I should have been using mip_width Review URL: http://codereview.chromium.org/174199 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24188 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/core')
-rw-r--r--o3d/core/cross/client.cc40
-rw-r--r--o3d/core/cross/client.h3
-rw-r--r--o3d/core/cross/command_buffer/renderer_cb.cc42
-rw-r--r--o3d/core/cross/command_buffer/renderer_cb.h30
-rw-r--r--o3d/core/cross/command_buffer/texture_cb.cc9
-rw-r--r--o3d/core/cross/command_buffer/texture_cb.h26
-rw-r--r--o3d/core/cross/gl/renderer_gl.cc38
-rw-r--r--o3d/core/cross/gl/renderer_gl.h32
-rw-r--r--o3d/core/cross/gl/texture_gl.cc27
-rw-r--r--o3d/core/cross/gl/texture_gl.h26
-rw-r--r--o3d/core/cross/pack_test.cc27
-rw-r--r--o3d/core/cross/renderer.cc70
-rw-r--r--o3d/core/cross/renderer.h113
-rw-r--r--o3d/core/cross/texture.cc28
-rw-r--r--o3d/core/cross/texture.h24
-rw-r--r--o3d/core/cross/texture_base.cc6
-rw-r--r--o3d/core/cross/texture_base.h2
-rw-r--r--o3d/core/win/d3d9/renderer_d3d9.cc77
-rw-r--r--o3d/core/win/d3d9/renderer_d3d9.h31
-rw-r--r--o3d/core/win/d3d9/texture_d3d9.cc69
-rw-r--r--o3d/core/win/d3d9/texture_d3d9.h27
21 files changed, 403 insertions, 344 deletions
diff --git a/o3d/core/cross/client.cc b/o3d/core/cross/client.cc
index cfbce23..4e8ebac 100644
--- a/o3d/core/cross/client.cc
+++ b/o3d/core/cross/client.cc
@@ -79,7 +79,6 @@ Client::Client(ServiceLocator* service_locator)
profiler_(service_locator),
renderer_(service_locator),
evaluation_counter_(service_locator),
- rendering_(false),
render_tree_called_(false),
render_mode_(RENDERMODE_CONTINUOUS),
event_manager_(),
@@ -225,7 +224,6 @@ void Client::ClearLostResourcesCallback() {
void Client::RenderClient(bool send_callback) {
ElapsedTimeTimer timer;
- rendering_ = true;
render_tree_called_ = false;
total_time_to_render_ = 0.0f;
@@ -247,18 +245,19 @@ void Client::RenderClient(bool send_callback) {
if (!rendergraph_root || rendergraph_root->children().empty()) {
renderer_->Clear(Float4(0.4f, 0.3f, 0.3f, 1.0f),
true, 1.0, true, 0, true);
+ renderer_->set_need_to_render(false);
} else if (rendergraph_root) {
RenderTree(rendergraph_root);
}
}
+ renderer_->FinishRendering();
+
// Call post render callback.
profiler_->ProfileStart("Post-render callback");
post_render_callback_manager_.Run(render_event_);
profiler_->ProfileStop("Post-render callback");
- renderer_->FinishRendering();
-
// Update Render stats.
render_event_.set_elapsed_time(
render_elapsed_time_timer_.GetElapsedTimeAndReset());
@@ -295,18 +294,25 @@ void Client::RenderClient(bool send_callback) {
metric_render_prims_rendered.AddSample(render_event_.primitives_rendered());
#endif // OS_WIN
}
-
- rendering_ = false;
}
// Executes draw calls for all visible shapes in a subtree
void Client::RenderTree(RenderNode *tree_root) {
- render_tree_called_ = true;
-
if (!renderer_.IsAvailable())
return;
+ if (!renderer_->rendering()) {
+ // Render tree can not be called if we are not rendering because all calls
+ // to RenderTree must happen inside renderer->StartRendering() /
+ // renderer->FinishRendering() calls.
+ O3D_ERROR(service_locator_)
+ << "RenderTree must not be called outside of rendering.";
+ return;
+ }
+
+ render_tree_called_ = true;
+
// Only render the shapes if BeginDraw() succeeds
profiler_->ProfileStart("RenderTree");
ElapsedTimeTimer time_to_render_timer;
@@ -406,13 +412,19 @@ String Client::ToDataURL() {
if (!renderer_.IsAvailable()) {
O3D_ERROR(service_locator_) << "No Render Device Available";
return dataurl::kEmptyDataURL;
+ }
+
+ if (renderer_->rendering()) {
+ O3D_ERROR(service_locator_)
+ << "Can not take a screenshot while rendering";
+ return dataurl::kEmptyDataURL;
+ }
+
+ Bitmap::Ref bitmap(renderer_->TakeScreenshot());
+ if (bitmap.IsNull()) {
+ return dataurl::kEmptyDataURL;
} else {
- Bitmap::Ref bitmap(renderer_->TakeScreenshot());
- if (bitmap.IsNull()) {
- return dataurl::kEmptyDataURL;
- } else {
- return bitmap->ToDataURL();
- }
+ return bitmap->ToDataURL();
}
}
diff --git a/o3d/core/cross/client.h b/o3d/core/cross/client.h
index 153e354..3ef307b 100644
--- a/o3d/core/cross/client.h
+++ b/o3d/core/cross/client.h
@@ -445,9 +445,6 @@ class Client {
ServiceDependency<Renderer> renderer_;
ServiceDependency<EvaluationCounter> evaluation_counter_;
- // Currently rendering.
- bool rendering_;
-
// RenderTree was called.
bool render_tree_called_;
diff --git a/o3d/core/cross/command_buffer/renderer_cb.cc b/o3d/core/cross/command_buffer/renderer_cb.cc
index c5d3641..69fdf2f 100644
--- a/o3d/core/cross/command_buffer/renderer_cb.cc
+++ b/o3d/core/cross/command_buffer/renderer_cb.cc
@@ -172,16 +172,7 @@ void RendererCB::Resize(int width, int height) {
SetClientSize(width, height);
}
-// Adds the BEGIN_FRAME command to the command buffer.
-bool RendererCB::BeginDraw() {
- ++render_frame_count_;
- DCHECK(helper_);
- helper_->AddCommand(command_buffer::BEGIN_FRAME, 0 , NULL);
- // Clear the client if we need to.
- if (clear_client_) {
- clear_client_ = false;
- Clear(Float4(0.5f, 0.5f, 0.5f, 1.0f), true, 1.0f, true, 0, true);
- }
+bool RendererCB::PlatformSpecificBeginDraw() {
return true;
}
@@ -207,29 +198,24 @@ void RendererCB::Clear(const Float4 &color,
helper_->AddCommand(command_buffer::CLEAR, 7, args);
}
-// Adds the END_FRAME command to the command buffer, and flushes the commands.
-void RendererCB::EndDraw() {
- ApplyDirtyStates();
- helper_->AddCommand(command_buffer::END_FRAME, 0 , NULL);
- helper_->WaitForToken(frame_token_);
- frame_token_ = helper_->InsertToken();
+void RendererCB::PlatformSpecificEndDraw() {
}
-bool RendererCB::StartRendering() {
- ++render_frame_count_;
- transforms_culled_ = 0;
- transforms_processed_ = 0;
- draw_elements_culled_ = 0;
- draw_elements_processed_ = 0;
- draw_elements_rendered_ = 0;
- primitives_rendered_ = 0;
-
+// Adds the BEGIN_FRAME command to the command buffer.
+bool RendererCB::PlatformSpecificStartRendering() {
// Any device issues are handled in the command buffer backend
+ DCHECK(helper_);
+ helper_->AddCommand(command_buffer::BEGIN_FRAME, 0 , NULL);
return true;
}
-void RendererCB::FinishRendering() {
+// Adds the END_FRAME command to the command buffer, and flushes the commands.
+void RendererCB::PlatformSpecificFinishRendering() {
// Any device issues are handled in the command buffer backend
+ ApplyDirtyStates();
+ helper_->AddCommand(command_buffer::END_FRAME, 0 , NULL);
+ helper_->WaitForToken(frame_token_);
+ frame_token_ = helper_->InsertToken();
}
void RendererCB::RenderElement(Element* element,
@@ -237,7 +223,7 @@ void RendererCB::RenderElement(Element* element,
Material* material,
ParamObject* override,
ParamCache* param_cache) {
- ++draw_elements_rendered_;
+ IncrementDrawElementsRendered();
State *current_state = material ? material->state() : NULL;
PushRenderStates(current_state);
ApplyDirtyStates();
@@ -340,7 +326,7 @@ void RendererCB::SetViewportInPixels(int left,
helper_->AddCommand(command_buffer::SET_VIEWPORT, 6, args);
}
-Bitmap::Ref RendererCB::TakeScreenshot() {
+Bitmap::Ref RendererCB::PlatformSpecificTakeScreenshot() {
return Bitmap::Ref();
}
diff --git a/o3d/core/cross/command_buffer/renderer_cb.h b/o3d/core/cross/command_buffer/renderer_cb.h
index 5df7936..59b1108 100644
--- a/o3d/core/cross/command_buffer/renderer_cb.h
+++ b/o3d/core/cross/command_buffer/renderer_cb.h
@@ -79,9 +79,6 @@ class RendererCB : public Renderer {
// Destroy() should be called before Init() is called again.
virtual void Destroy();
- // Prepares the rendering device for subsequent draw calls.
- virtual bool BeginDraw();
-
// Clears the current buffers.
virtual void Clear(const Float4 &color,
bool color_flag,
@@ -90,15 +87,6 @@ class RendererCB : public Renderer {
int stencil,
bool stencil_flag);
- // Notifies the renderer that the draw calls for this frame are completed.
- virtual void EndDraw();
-
- // Does any pre-rendering preparation
- virtual bool StartRendering();
-
- // Presents the results of the draw calls for this frame.
- virtual void FinishRendering();
-
// Renders this Element using the parameters from override first, followed by
// the draw_element, followed by params on this Primitive and material.
// Parameters:
@@ -141,9 +129,6 @@ class RendererCB : public Renderer {
return RenderDepthStencilSurface::Ref();
}
- // Overridden from Renderer.
- virtual Bitmap::Ref TakeScreenshot();
-
// Gets the allocator for vertex buffer IDs.
IdAllocator &vertex_buffer_ids() { return vertex_buffer_ids_; }
@@ -192,6 +177,21 @@ class RendererCB : public Renderer {
RendererCB(ServiceLocator* service_locator, unsigned int command_buffer_size,
unsigned int transfer_memory_size);
+ // Overridden from Renderer.
+ virtual bool PlatformSpecificBeginDraw();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificEndDraw();
+
+ // Overridden from Renderer.
+ virtual bool PlatformSpecificStartRendering();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificFinishRendering();
+
+ // Overridden from Renderer.
+ virtual Bitmap::Ref PlatformSpecificTakeScreenshot();
+
// Creates a platform specific ParamCache.
virtual ParamCache* CreatePlatformSpecificParamCache();
diff --git a/o3d/core/cross/command_buffer/texture_cb.cc b/o3d/core/cross/command_buffer/texture_cb.cc
index 56b7e55..bfa8684 100644
--- a/o3d/core/cross/command_buffer/texture_cb.cc
+++ b/o3d/core/cross/command_buffer/texture_cb.cc
@@ -353,7 +353,8 @@ bool Texture2DCB::Unlock(int level) {
return true;
}
-RenderSurface::Ref Texture2DCB::GetRenderSurface(int mip_level, Pack *pack) {
+RenderSurface::Ref Texture2DCB::PlatformSpecificGetRenderSurface(
+ int mip_level) {
DCHECK_LT(mip_level, levels());
// TODO: Provide an implementation for render surface extraction.
return RenderSurface::Ref(NULL);
@@ -522,9 +523,9 @@ bool TextureCUBECB::Unlock(CubeFace face, int level) {
return false;
}
-RenderSurface::Ref TextureCUBECB::GetRenderSurface(TextureCUBE::CubeFace face,
- int mip_level,
- Pack *pack) {
+RenderSurface::Ref TextureCUBECB::PlatformSpecificGetRenderSurface(
+ TextureCUBE::CubeFace face,
+ int mip_level) {
DCHECK_LT(mip_level, levels());
// TODO: Provide an implementation for render surface extraction.
return RenderSurface::Ref(NULL);
diff --git a/o3d/core/cross/command_buffer/texture_cb.h b/o3d/core/cross/command_buffer/texture_cb.h
index 6ccf9cc..c2aa224 100644
--- a/o3d/core/cross/command_buffer/texture_cb.h
+++ b/o3d/core/cross/command_buffer/texture_cb.h
@@ -76,14 +76,6 @@ class Texture2DCB : public Texture2D {
const void* src_data,
int src_pitch);
- // Returns a RenderSurface object associated with a mip_level of a texture.
- // Parameters:
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(int mip_level, Pack *pack);
-
// Returns the implementation-specific texture handle for this texture.
virtual void* GetTextureHandle() const {
return reinterpret_cast<void*>(resource_id_);
@@ -103,6 +95,9 @@ class Texture2DCB : public Texture2D {
// Overridden from Texture2D
virtual bool Unlock(int level);
+ // Overridden from Texture2D
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(int mip_level);
+
private:
// Initializes the Texture2DCB from a preexisting OpenCB texture handle
// and raw Bitmap data.
@@ -158,18 +153,6 @@ class TextureCUBECB : public TextureCUBE {
const void* src_data,
int src_pitch);
- // Returns a RenderSurface object associated with a given cube face and
- // mip_level of a texture.
- // Parameters:
- // face: [in] The cube face from which to extract the surface.
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(CubeFace face,
- int level,
- Pack* pack);
-
// Returns the implementation-specific texture handle for this texture.
virtual void* GetTextureHandle() const {
return reinterpret_cast<void*>(resource_id_);
@@ -190,6 +173,9 @@ class TextureCUBECB : public TextureCUBE {
// Overridden from TextureCUBE
virtual bool Unlock(CubeFace face, int level);
+ // Overridden from TextureCUBE.
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(CubeFace face,
+ int level);
private:
// Creates a texture from a pre-existing texture resource.
TextureCUBECB(ServiceLocator* service_locator,
diff --git a/o3d/core/cross/gl/renderer_gl.cc b/o3d/core/cross/gl/renderer_gl.cc
index c4a0a30..d4422ff 100644
--- a/o3d/core/cross/gl/renderer_gl.cc
+++ b/o3d/core/cross/gl/renderer_gl.cc
@@ -1159,7 +1159,6 @@ void RendererGL::Clear(const Float4 &color,
(depth_flag ? GL_DEPTH_BUFFER_BIT : 0) |
(stencil_flag ? GL_STENCIL_BUFFER_BIT : 0));
CHECK_GL_ERROR();
- set_need_to_render(false);
}
// Updates the helper constant used for the D3D -> GL remapping.
@@ -1229,22 +1228,9 @@ bool RendererGL::SetFullscreen(bool fullscreen,
return true;
}
-bool RendererGL::StartRendering() {
+bool RendererGL::PlatformSpecificStartRendering() {
DLOG_FIRST_N(INFO, 10) << "RendererGL StartRendering";
MakeCurrentLazy();
- ++render_frame_count_;
- transforms_culled_ = 0;
- transforms_processed_ = 0;
- draw_elements_culled_ = 0;
- draw_elements_processed_ = 0;
- draw_elements_rendered_ = 0;
- primitives_rendered_ = 0;
-
- // Clear the client if we need to.
- if (clear_client_) {
- clear_client_ = false;
- Clear(Float4(0.5f, 0.5f, 0.5f, 1.0f), true, 1.0f, true, 0, true);
- }
// Currently always returns true.
// Should be modified if current behavior changes.
@@ -1255,15 +1241,11 @@ bool RendererGL::StartRendering() {
// Clears the color, depth and stncil buffers and prepares GL for rendering
// the frame.
// Returns true on success.
-bool RendererGL::BeginDraw() {
+bool RendererGL::PlatformSpecificBeginDraw() {
DLOG_FIRST_N(INFO, 10) << "RendererGL BeginDraw";
- set_need_to_render(true);
MakeCurrentLazy();
- // Reset the viewport.
- SetViewport(Float4(0.0f, 0.0f, 1.0f, 1.0f), Float2(0.0f, 1.0f));
-
// Currently always returns true.
// Should be modified if current behavior changes.
CHECK_GL_ERROR();
@@ -1278,7 +1260,7 @@ void RendererGL::RenderElement(Element* element,
ParamCache* param_cache) {
DCHECK(IsCurrent());
DLOG_FIRST_N(INFO, 10) << "RendererGL RenderElement";
- ++draw_elements_rendered_;
+ IncrementDrawElementsRendered();
State *current_state = material ? material->state() : NULL;
PushRenderStates(current_state);
SetChangedStates();
@@ -1318,18 +1300,14 @@ void RendererGL::SetBackBufferPlatformSpecific() {
}
// Executes a post rendering step
-void RendererGL::EndDraw() {
+void RendererGL::PlatformSpecificEndDraw() {
DLOG_FIRST_N(INFO, 10) << "RendererGL EndDraw";
DCHECK(IsCurrent());
SetChangedStates();
- set_need_to_render(false);
}
// Swaps the buffers.
-void RendererGL::FinishRendering() {
- if (need_to_render())
- return;
-
+void RendererGL::PlatformSpecificFinishRendering() {
DLOG_FIRST_N(INFO, 10) << "RendererGL Present";
DCHECK(IsCurrent());
SetChangedStates();
@@ -1532,15 +1510,11 @@ RenderDepthStencilSurface::Ref RendererGL::CreateDepthStencilSurface(
height));
}
-Bitmap::Ref RendererGL::TakeScreenshot() {;
+Bitmap::Ref RendererGL::PlatformSpecificTakeScreenshot() {
MakeCurrentLazy();
Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator()));
bitmap->Allocate(Texture::ARGB8, width(), height(), 1, Bitmap::IMAGE);
- // Note: glReadPixels captures the alpha component of the frame buffer as well
- // as the color components, the browser usually ignores the alpha channel when
- // drawing to the screen, so unless the alpha is 1, the png image generated
- // might exhibit suprise translucency.
::glReadPixels(0, 0, width(), height(), GL_BGRA, GL_UNSIGNED_BYTE,
bitmap->image_data());
return bitmap;
diff --git a/o3d/core/cross/gl/renderer_gl.h b/o3d/core/cross/gl/renderer_gl.h
index 2ced616..c02b8f7 100644
--- a/o3d/core/cross/gl/renderer_gl.h
+++ b/o3d/core/cross/gl/renderer_gl.h
@@ -65,20 +65,6 @@ class RendererGL : public Renderer {
// Released all hardware resources.
virtual void Destroy();
- // This method should be called before any draw calls take place in a
- // frame. It clears the back buffer, stencil and depth buffers.
- // Returns true on success.
- virtual bool BeginDraw();
-
- // Finalizes the drawing of the frame.
- virtual void EndDraw();
-
- // Does any pre-rendering preparation
- virtual bool StartRendering();
-
- // Presents the results of the draw calls for this frame.
- virtual void FinishRendering();
-
// Turns fullscreen display on or off.
// Parameters:
// fullscreen: true for fullscreen, false for in-browser display
@@ -145,9 +131,6 @@ class RendererGL : public Renderer {
int height);
// Overridden from Renderer.
- virtual Bitmap::Ref TakeScreenshot();
-
- // Overridden from Renderer.
virtual const int* GetRGBAUByteNSwizzleTable();
// Makes this renderer active on the current thread if it is not active
@@ -185,6 +168,21 @@ class RendererGL : public Renderer {
explicit RendererGL(ServiceLocator* service_locator);
// Overridden from Renderer.
+ virtual bool PlatformSpecificBeginDraw();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificEndDraw();
+
+ // Overridden from Renderer.
+ virtual bool PlatformSpecificStartRendering();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificFinishRendering();
+
+ // Overridden from Renderer.
+ virtual Bitmap::Ref PlatformSpecificTakeScreenshot();
+
+ // Overridden from Renderer.
virtual ParamCache* CreatePlatformSpecificParamCache();
// Sets the viewport. This is the platform specific version.
diff --git a/o3d/core/cross/gl/texture_gl.cc b/o3d/core/cross/gl/texture_gl.cc
index 65a832f..3d8b1f0 100644
--- a/o3d/core/cross/gl/texture_gl.cc
+++ b/o3d/core/cross/gl/texture_gl.cc
@@ -527,9 +527,9 @@ bool Texture2DGL::Unlock(int level) {
return true;
}
-RenderSurface::Ref Texture2DGL::GetRenderSurface(int mip_level, Pack *pack) {
+RenderSurface::Ref Texture2DGL::PlatformSpecificGetRenderSurface(
+ int mip_level) {
DCHECK_LT(mip_level, levels());
- DCHECK(pack);
if (!render_surfaces_enabled()) {
O3D_ERROR(service_locator())
<< "Attempting to get RenderSurface from non-render-surface-enabled"
@@ -544,19 +544,13 @@ RenderSurface::Ref Texture2DGL::GetRenderSurface(int mip_level, Pack *pack) {
return RenderSurface::Ref(NULL);
}
- RenderSurface::Ref render_surface(new RenderSurfaceGL(
+ return RenderSurface::Ref(new RenderSurfaceGL(
service_locator(),
width()>> mip_level,
height() >> mip_level,
0,
mip_level,
this));
-
- if (!render_surface.IsNull()) {
- RegisterSurface(render_surface.Get(), pack);
- }
-
- return render_surface;
}
const Texture::RGBASwizzleIndices& Texture2DGL::GetABGR32FSwizzleIndices() {
@@ -693,11 +687,10 @@ void TextureCUBEGL::UpdateBackedMipLevel(unsigned int level,
resize_to_pot_);
}
-RenderSurface::Ref TextureCUBEGL::GetRenderSurface(TextureCUBE::CubeFace face,
- int mip_level,
- Pack *pack) {
+RenderSurface::Ref TextureCUBEGL::PlatformSpecificGetRenderSurface(
+ TextureCUBE::CubeFace face,
+ int mip_level) {
DCHECK_LT(mip_level, levels());
- DCHECK(pack);
if (!render_surfaces_enabled()) {
O3D_ERROR(service_locator())
<< "Attempting to get RenderSurface from non-render-surface-enabled"
@@ -712,19 +705,13 @@ RenderSurface::Ref TextureCUBEGL::GetRenderSurface(TextureCUBE::CubeFace face,
return RenderSurface::Ref(NULL);
}
- RenderSurface::Ref render_surface(new RenderSurfaceGL(
+ return RenderSurface::Ref(new RenderSurfaceGL(
service_locator(),
edge_length() >> mip_level,
edge_length() >> mip_level,
kCubemapFaceList[face],
mip_level,
this));
-
- if (!render_surface.IsNull()) {
- RegisterSurface(render_surface.Get(), pack);
- }
-
- return render_surface;
}
void TextureCUBEGL::SetRect(TextureCUBE::CubeFace face,
diff --git a/o3d/core/cross/gl/texture_gl.h b/o3d/core/cross/gl/texture_gl.h
index a107de6..140b7e8 100644
--- a/o3d/core/cross/gl/texture_gl.h
+++ b/o3d/core/cross/gl/texture_gl.h
@@ -96,14 +96,6 @@ class Texture2DGL : public Texture2D {
// Gets the GL texture handle.
GLuint gl_texture() const { return gl_texture_; }
- // Returns a RenderSurface object associated with a mip_level of a texture.
- // Parameters:
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(int mip_level, Pack *pack);
-
// Gets a RGBASwizzleIndices that contains a mapping from
// RGBA to the internal format used by the rendering API.
virtual const RGBASwizzleIndices& GetABGR32FSwizzleIndices();
@@ -115,6 +107,9 @@ class Texture2DGL : public Texture2D {
// Overridden from Texture2D
virtual bool Unlock(int level);
+ // Overridden from Texture2D
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(int mip_level);
+
private:
// Initializes the Texture2DGL from a preexisting OpenGL texture handle
// and raw Bitmap data.
@@ -190,18 +185,6 @@ class TextureCUBEGL : public TextureCUBE {
// Gets the GL texture handle.
GLuint gl_texture() const { return gl_texture_; }
- // Returns a RenderSurface object associated with a given cube face and
- // mip_level of a texture.
- // Parameters:
- // face: [in] The cube face from which to extract the surface.
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(CubeFace face,
- int level,
- Pack* pack);
-
// Gets a RGBASwizzleIndices that contains a mapping from
// RGBA to the internal format used by the rendering API.
virtual const RGBASwizzleIndices& GetABGR32FSwizzleIndices();
@@ -213,6 +196,9 @@ class TextureCUBEGL : public TextureCUBE {
// Overridden from TextureCUBE
virtual bool Unlock(CubeFace face, int level);
+ // Overridden from TextureCUBE.
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(CubeFace face,
+ int level);
private:
// Creates a texture from a pre-existing GL texture object.
TextureCUBEGL(ServiceLocator* service_locator,
diff --git a/o3d/core/cross/pack_test.cc b/o3d/core/cross/pack_test.cc
index a32e2ea..5aca47f 100644
--- a/o3d/core/cross/pack_test.cc
+++ b/o3d/core/cross/pack_test.cc
@@ -34,6 +34,7 @@
#include "core/cross/pack.h"
#include "core/cross/object_manager.h"
+#include "core/cross/error_status.h"
#include "core/cross/service_dependency.h"
#include "core/cross/transform.h"
#include "tests/common/win/testing_common.h"
@@ -44,12 +45,22 @@ class PackTest : public testing::Test {
public:
PackTest()
- : object_manager_(g_service_locator) {}
+ : object_manager_(g_service_locator),
+ error_status_(g_service_locator) {
+ }
ObjectManager* object_manager() { return object_manager_.Get(); }
+ // Checks if an error has occured on the client then clears the error.
+ bool CheckErrorExists() {
+ bool have_error = !error_status_.GetLastError().empty();
+ error_status_.ClearLastError();
+ return have_error;
+ }
+
private:
ServiceDependency<ObjectManager> object_manager_;
+ ErrorStatus error_status_;
};
// Test basic Pack creation and destruction.
@@ -115,9 +126,12 @@ TEST_F(PackTest, PackLookup) {
// Validate the semantics of removal of objects from a Pack.
TEST_F(PackTest, RemoveObject) {
Pack* pack = object_manager()->CreatePack();
+ ASSERT_TRUE(pack != NULL);
Transform* transform = pack->Create<Transform>();
+ ASSERT_TRUE(transform != NULL);
transform->set_name("Transform");
Transform* transform2 = pack->Create<Transform>();
+ ASSERT_TRUE(transform2 != NULL);
const String transform_name(transform->name());
const Id id(transform->id());
@@ -134,6 +148,17 @@ TEST_F(PackTest, RemoveObject) {
EXPECT_TRUE(pack->Get<Transform>(
transform2->name())[0] == transform2);
+ Pack* pack2 = object_manager()->CreatePack();
+ ASSERT_TRUE(pack2 != NULL);
+ Transform* transform3 = pack2->Create<Transform>();
+ ASSERT_TRUE(transform3 != NULL);
+
+ // Check that trying to remove something not in the pack returns false but
+ // does NOT generate an error.
+ EXPECT_FALSE(pack->RemoveObject(transform3));
+ EXPECT_FALSE(CheckErrorExists());
+
+ EXPECT_TRUE(pack2->Destroy());
EXPECT_TRUE(pack->Destroy());
}
diff --git a/o3d/core/cross/renderer.cc b/o3d/core/cross/renderer.cc
index 65ea374..8900ddf 100644
--- a/o3d/core/cross/renderer.cc
+++ b/o3d/core/cross/renderer.cc
@@ -100,10 +100,13 @@ bool Renderer::IsForceSoftwareRenderer() {
}
Renderer::Renderer(ServiceLocator* service_locator)
- : clear_client_(true),
- need_to_render_(true),
- current_render_surface_(NULL),
+ : current_render_surface_(NULL),
current_depth_surface_(NULL),
+ service_locator_(service_locator),
+ service_(service_locator, this),
+ features_(service_locator),
+ viewport_(0.0f, 0.0f, 1.0f, 1.0f),
+ depth_range_(0.0f, 1.0f),
render_frame_count_(0),
transforms_processed_(0),
transforms_culled_(0),
@@ -111,11 +114,10 @@ Renderer::Renderer(ServiceLocator* service_locator)
draw_elements_culled_(0),
draw_elements_rendered_(0),
primitives_rendered_(0),
- viewport_(0.0f, 0.0f, 1.0f, 1.0f),
- depth_range_(0.0f, 1.0f),
- service_locator_(service_locator),
- service_(service_locator, this),
- features_(service_locator),
+ clear_client_(true),
+ need_to_render_(true),
+ rendering_(false),
+ drawing_(false),
width_(0),
height_(0),
render_width_(0),
@@ -244,6 +246,58 @@ void Renderer::SetClientSize(int width, int height) {
clear_client_ = true;
}
+bool Renderer::StartRendering() {
+ ++render_frame_count_;
+ rendering_ = true;
+ transforms_culled_ = 0;
+ transforms_processed_ = 0;
+ draw_elements_culled_ = 0;
+ draw_elements_processed_ = 0;
+ draw_elements_rendered_ = 0;
+ primitives_rendered_ = 0;
+
+ bool result = PlatformSpecificStartRendering();
+ if (result) {
+ set_need_to_render(true);
+ // Clear the client if we need to.
+ if (clear_client_) {
+ clear_client_ = false;
+ Clear(Float4(0.5f, 0.5f, 0.5f, 1.0f), true, 1.0f, true, 0, true);
+ }
+ }
+ return result;
+}
+
+bool Renderer::BeginDraw() {
+ DCHECK(rendering_);
+ bool result = PlatformSpecificBeginDraw();
+ if (result) {
+ drawing_ = true;
+ // Reset the viewport.
+ SetViewport(Float4(0.0f, 0.0f, 1.0f, 1.0f), Float2(0.0f, 1.0f));
+ }
+ return result;
+}
+
+void Renderer::EndDraw() {
+ PlatformSpecificEndDraw();
+ drawing_ = false;
+}
+
+void Renderer::FinishRendering() {
+ PlatformSpecificFinishRendering();
+ set_need_to_render(false);
+ rendering_ = false;
+}
+
+Bitmap::Ref Renderer::TakeScreenshot() {
+ if (rendering_) {
+ O3D_ERROR(service_locator())
+ << "Can not take a screenshot while rendering";
+ return Bitmap::Ref(NULL);
+ }
+ return PlatformSpecificTakeScreenshot();
+}
void Renderer::GetViewport(Float4* viewport, Float2* depth_range) {
DCHECK(viewport);
diff --git a/o3d/core/cross/renderer.h b/o3d/core/cross/renderer.h
index e0fdde9..8c850ab 100644
--- a/o3d/core/cross/renderer.h
+++ b/o3d/core/cross/renderer.h
@@ -171,16 +171,31 @@ class Renderer {
virtual void Destroy() = 0;
// Prepares the rendering device for subsequent draw calls.
- virtual bool BeginDraw() = 0;
-
- // Notifies the renderer that the draw calls for this frame are completed.
- virtual void EndDraw() = 0;
-
- // Does any pre-rendering preparation
- virtual bool StartRendering() = 0;
+ // This is called during a RenderTree and can be called mutliple times
+ // during a single frame.
+ // NOTE: See StartRendering!
+ bool BeginDraw();
+
+ // This is called during a RenderTree and can be called mutliple times during
+ // a single frame. It gives the renderer a chance to flush state before
+ // returning to JavaScript if JavaScript is calling RenderTree directly.
+ // NOTE: See StartRendering!
+ void EndDraw();
+
+ // Does any pre-rendering preparation.
+ // The order of operations is
+ // StartRendering()
+ // BeginDraw();
+ // EndDraw()
+ // BeginDraw();
+ // EndDraw()
+ // BeginDraw();
+ // EndDraw()
+ // FinishRendering(); // <- Presents the results.
+ bool StartRendering();
// Presents the results of the draw calls for this frame.
- virtual void FinishRendering() = 0;
+ void FinishRendering();
// Returns whether a render is required.
bool need_to_render() const {
@@ -358,13 +373,26 @@ class Renderer {
int height) = 0;
// Returns the screen as a Bitmap. Will return a null reference on error.
- virtual Bitmap::Ref TakeScreenshot() = 0;
+ Bitmap::Ref TakeScreenshot();
ServiceLocator* service_locator() const { return service_locator_; }
// Returns the type of Param needed for a particular state.
const ObjectBase::Class* GetStateParamType(const String& state_name) const;
+ // Whether we are currently rendering (between StartRendering /
+ // FinishRendering calls).
+ // NOTE: See StartRendering!
+ bool rendering() const {
+ return rendering_;
+ }
+
+ // Whether we are currently drawing (between BeginDraw / EndDraw calls).
+ // NOTE: See StartRendering!
+ bool drawing() const {
+ return drawing_;
+ }
+
// Get the client area's width.
int width() const {
return width_;
@@ -436,6 +464,10 @@ class Renderer {
++draw_elements_culled_;
}
+ void IncrementDrawElementsRendered() {
+ ++draw_elements_rendered_;
+ }
+
void AddPrimitivesRendered(int amount_to_add) {
primitives_rendered_ += amount_to_add;
}
@@ -542,6 +574,20 @@ class Renderer {
int levels,
bool enable_render_surfaces) = 0;
+ // The platform specific part of BeginDraw.
+ virtual bool PlatformSpecificBeginDraw() = 0;
+
+ // The platform specific part of EndDraw.
+ virtual void PlatformSpecificEndDraw() = 0;
+
+ // The platform specific part of StartRendering.
+ virtual bool PlatformSpecificStartRendering() = 0;
+
+ // The platform specific part of EndRendering.
+ virtual void PlatformSpecificFinishRendering() = 0;
+
+ virtual Bitmap::Ref PlatformSpecificTakeScreenshot() = 0;
+
// Sets the viewport. This is the platform specific version.
virtual void SetViewportInPixels(int left,
int top,
@@ -553,25 +599,10 @@ class Renderer {
// Sets the client's size. Derived classes must call this on Init and Resize.
void SetClientSize(int width, int height);
- // Whether we need to clear the entire client area next render.
- bool clear_client_;
-
- // Whether a render is required.
- bool need_to_render_;
-
// The current render surfaces. NULL = no surface.
RenderSurface* current_render_surface_;
RenderDepthStencilSurface* current_depth_surface_;
- int render_frame_count_; // count of times we've rendered frame.
- int transforms_processed_; // count of transforms processed this frame.
- int transforms_culled_; // count of transforms culled this frame.
- int draw_elements_processed_; // count of draw elements processed this frame.
- int draw_elements_culled_; // count of draw elements culled this frame.
- int draw_elements_rendered_; // count of draw elements culled this frame.
- int primitives_rendered_; // count of primitives (tris, lines)
- // rendered this frame.
-
Sampler::Ref error_sampler_; // sampler used when one is missing.
Texture::Ref error_texture_; // texture used when one is missing.
Texture::Ref fallback_error_texture_; // texture used when error_texture is
@@ -591,12 +622,6 @@ class Renderer {
// State object holding the default state settings.
State::Ref default_state_;
- // Current viewport setting.
- Float4 viewport_;
-
- // Current depth range.
- Float2 depth_range_;
-
// Lost Resources Callbacks.
LostResourcesCallbackManager lost_resources_callback_manager_;
@@ -617,6 +642,34 @@ class Renderer {
ServiceImplementation<Renderer> service_;
ServiceDependency<Features> features_;
+ // Current viewport setting.
+ Float4 viewport_;
+
+ // Current depth range.
+ Float2 depth_range_;
+
+ int render_frame_count_; // count of times we've rendered frame.
+ int transforms_processed_; // count of transforms processed this frame.
+ int transforms_culled_; // count of transforms culled this frame.
+ int draw_elements_processed_; // count of draw elements processed this frame.
+ int draw_elements_culled_; // count of draw elements culled this frame.
+ int draw_elements_rendered_; // count of draw elements culled this frame.
+ int primitives_rendered_; // count of primitives (tris, lines)
+ // rendered this frame.
+
+ // Whether we need to clear the entire client area next render.
+ bool clear_client_;
+
+ // Whether a render is required.
+ bool need_to_render_;
+
+ // Whether we are currently rendering (between StartRendering /
+ // FinishRendering calls)
+ bool rendering_;
+
+ // Whether or not we are drawing (between BeingDraw/EndDraw calls)
+ bool drawing_;
+
int width_; // width of the client area in pixels
int height_; // height of the client area in pixels
diff --git a/o3d/core/cross/texture.cc b/o3d/core/cross/texture.cc
index 4ef14fc..9d3a0a9 100644
--- a/o3d/core/cross/texture.cc
+++ b/o3d/core/cross/texture.cc
@@ -60,7 +60,8 @@ Texture2D::Texture2D(ServiceLocator* service_locator,
int levels,
bool enable_render_surfaces)
: Texture(service_locator, format, levels, enable_render_surfaces),
- locked_levels_(0) {
+ locked_levels_(0),
+ surface_map_(levels) {
RegisterReadOnlyParamRef(kWidthParamName, &width_param_);
RegisterReadOnlyParamRef(kHeightParamName, &height_param_);
width_param_->set_read_only_value(width);
@@ -306,6 +307,18 @@ ObjectBase::Ref Texture2D::Create(ServiceLocator* service_locator) {
return ObjectBase::Ref();
}
+RenderSurface::Ref Texture2D::GetRenderSurface(int mip_level) {
+ if (mip_level < 0 || mip_level >= levels()) {
+ O3D_ERROR(service_locator()) << "mip level out of range";
+ return RenderSurface::Ref(NULL);
+ }
+ if (surface_map_[mip_level].IsNull()) {
+ surface_map_[mip_level] = RenderSurface::Ref(
+ PlatformSpecificGetRenderSurface(mip_level));
+ }
+ return surface_map_[mip_level];
+}
+
Texture2D::LockHelper::LockHelper(Texture2D* texture, int level)
: texture_(texture),
level_(level),
@@ -338,6 +351,7 @@ TextureCUBE::TextureCUBE(ServiceLocator* service_locator,
: Texture(service_locator, format, levels, enable_render_surfaces) {
for (unsigned int i = 0; i < 6; ++i) {
locked_levels_[i] = 0;
+ surface_maps_[i].resize(levels);
}
RegisterReadOnlyParamRef(kEdgeLengthParamName, &edge_length_param_);
edge_length_param_->set_read_only_value(edge_length);
@@ -374,6 +388,18 @@ ObjectBase::Ref TextureCUBE::Create(ServiceLocator* service_locator) {
return ObjectBase::Ref();
}
+RenderSurface::Ref TextureCUBE::GetRenderSurface(CubeFace face, int mip_level) {
+ if (mip_level < 0 || mip_level >= levels()) {
+ O3D_ERROR(service_locator()) << "mip level out of range";
+ return RenderSurface::Ref(NULL);
+ }
+ if (surface_maps_[face][mip_level].IsNull()) {
+ surface_maps_[face][mip_level] = RenderSurface::Ref(
+ PlatformSpecificGetRenderSurface(face, mip_level));
+ }
+ return surface_maps_[face][mip_level];
+}
+
void TextureCUBE::DrawImage(const Bitmap& src_img, int src_mip,
int src_x, int src_y,
int src_width, int src_height,
diff --git a/o3d/core/cross/texture.h b/o3d/core/cross/texture.h
index 79ddae2..fcaf75a 100644
--- a/o3d/core/cross/texture.h
+++ b/o3d/core/cross/texture.h
@@ -122,10 +122,9 @@ class Texture2D : public Texture {
// Returns a RenderSurface object associated with a mip_level of a texture.
// Parameters:
// mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
// Returns:
// Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(int mip_level, Pack* pack) = 0;
+ RenderSurface::Ref GetRenderSurface(int mip_level);
// Copy pixels from source bitmap to certain mip level.
// Scales if the width and height of source and dest do not match.
@@ -197,6 +196,10 @@ class Texture2D : public Texture {
// true if the operation succeeds
virtual bool Unlock(int level) = 0;
+ // The platform specific part of GetRenderSurface.
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(
+ int mip_level) = 0;
+
// Returns true if the mip-map level has been locked.
bool IsLocked(unsigned int level) {
DCHECK_LT(static_cast<int>(level), levels());
@@ -210,6 +213,10 @@ class Texture2D : public Texture {
friend class IClassManager;
static ObjectBase::Ref Create(ServiceLocator* service_locator);
+ typedef std::vector<RenderSurface::Ref> MipToRenderSurfaceMap;
+
+ MipToRenderSurfaceMap surface_map_;
+
// The width of the texture, in texels.
ParamInteger::Ref width_param_;
// The height of the texture, in texels.
@@ -308,12 +315,9 @@ class TextureCUBE : public Texture {
// Parameters:
// face: [in] The cube face from which to extract the surface.
// mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
// Returns:
// Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(CubeFace face,
- int level,
- Pack* pack) = 0;
+ RenderSurface::Ref GetRenderSurface(CubeFace face, int level);
// Copy pixels from source bitmap to certain mip level.
// Scales if the width and height of source and dest do not match.
@@ -390,6 +394,10 @@ class TextureCUBE : public Texture {
// true if the operation succeeds
virtual bool Unlock(CubeFace face, int level) = 0;
+ // The platform specific part of GetRenderSurface.
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(
+ CubeFace face, int level) = 0;
+
// Returns true if the mip-map level has been locked.
bool IsLocked(unsigned int level, CubeFace face) {
DCHECK_LT(static_cast<int>(level), levels());
@@ -404,6 +412,10 @@ class TextureCUBE : public Texture {
friend class IClassManager;
static ObjectBase::Ref Create(ServiceLocator* service_locator);
+ typedef std::vector<RenderSurface::Ref> MipToRenderSurfaceMap;
+
+ MipToRenderSurfaceMap surface_maps_[NUMBER_OF_FACES];
+
// The length of each edge of the cube, in texels.
ParamInteger::Ref edge_length_param_;
diff --git a/o3d/core/cross/texture_base.cc b/o3d/core/cross/texture_base.cc
index f9825fb..6e4a81a 100644
--- a/o3d/core/cross/texture_base.cc
+++ b/o3d/core/cross/texture_base.cc
@@ -58,12 +58,6 @@ Texture::Texture(ServiceLocator* service_locator,
levels_param_->set_read_only_value(levels);
}
-void Texture::RegisterSurface(RenderSurface* surface, Pack* pack) {
- DCHECK(surface);
- DCHECK(pack);
- return pack->RegisterObject(surface);
-}
-
ObjectBase::Ref ParamTexture::Create(ServiceLocator* service_locator) {
return ObjectBase::Ref(new ParamTexture(service_locator, false, false));
}
diff --git a/o3d/core/cross/texture_base.h b/o3d/core/cross/texture_base.h
index 1c40d55..7b64a94 100644
--- a/o3d/core/cross/texture_base.h
+++ b/o3d/core/cross/texture_base.h
@@ -133,8 +133,6 @@ class Texture : public ParamObject {
format_ = format;
}
- static void RegisterSurface(RenderSurface* surface, Pack* pack);
-
private:
// The number of mipmap levels contained in this texture.
ParamInteger::Ref levels_param_;
diff --git a/o3d/core/win/d3d9/renderer_d3d9.cc b/o3d/core/win/d3d9/renderer_d3d9.cc
index 3cad2d9..01ddd1f 100644
--- a/o3d/core/win/d3d9/renderer_d3d9.cc
+++ b/o3d/core/win/d3d9/renderer_d3d9.cc
@@ -1040,7 +1040,6 @@ void RendererD3D9::Clear(const Float4 &color,
color[3]),
depth,
stencil));
- set_need_to_render(false);
}
void RendererD3D9::SetViewportInPixels(int left,
@@ -1367,45 +1366,23 @@ bool RendererD3D9::SetFullscreen(bool fullscreen,
}
// Resets the rendering stats and
-bool RendererD3D9::StartRendering() {
- ++render_frame_count_;
- transforms_culled_ = 0;
- transforms_processed_ = 0;
- draw_elements_culled_ = 0;
- draw_elements_processed_ = 0;
- draw_elements_rendered_ = 0;
- primitives_rendered_ = 0;
-
+bool RendererD3D9::PlatformSpecificStartRendering() {
// Determine whether the device is lost, resetting if possible.
TestLostDevice();
- // Only perform ops with the device if we have it.
- if (have_device_) {
- // Clear the client if we need to.
- if (clear_client_) {
- clear_client_ = false;
- Clear(Float4(0.5f, 0.5f, 0.5f, 1.0f), true, 1.0f, true, 0, true);
- }
- return true;
- } else {
- // Return false if we have lost the device.
- return false;
- }
+ return have_device_;
}
-// prepares DX9 for rendering the frame. Returns true on success.
-bool RendererD3D9::BeginDraw() {
+// prepares DX9 for rendering PART of the frame. Returns true on success.
+bool RendererD3D9::PlatformSpecificBeginDraw() {
// Only perform ops with the device if we have it.
if (have_device_) {
- set_need_to_render(true);
if (!HR(d3d_device_->GetRenderTarget(0, &back_buffer_surface_)))
return false;
if (!HR(d3d_device_->GetDepthStencilSurface(&back_buffer_depth_surface_)))
return false;
if (!HR(d3d_device_->BeginScene()))
return false;
- // Reset the viewport.
- SetViewport(Float4(0.0f, 0.0f, 1.0f, 1.0f), Float2(0.0f, 1.0f));
return true;
} else {
back_buffer_surface_ = NULL;
@@ -1416,6 +1393,8 @@ bool RendererD3D9::BeginDraw() {
}
}
+// TODO(gman): Why is this code in here? Shouldn't this use O3D to render this
+// instead of D3D?
void RendererD3D9::ShowFullscreenMessage(float elapsed_time,
float display_duration) {
RECT rect;
@@ -1473,9 +1452,22 @@ void RendererD3D9::ShowFullscreenMessage(float elapsed_time,
d3d_device_->SetRenderState(D3DRS_ZENABLE, z_enable);
}
-// Notifies DX9 that rendering of the frame is complete and swaps the buffers.
-void RendererD3D9::EndDraw() {
+// NOTE: End draw can be called multiple times per frame. If want something
+// to happen only once per frame it belongs in FinishRendering.
+void RendererD3D9::PlatformSpecificEndDraw() {
+ if (have_device_) {
+ HR(d3d_device_->EndScene());
+
+ // Release the back-buffer references.
+ back_buffer_surface_ = NULL;
+ back_buffer_depth_surface_ = NULL;
+ }
+}
+
+void RendererD3D9::PlatformSpecificFinishRendering() {
if (have_device_) {
+ // No need to call Present(...) if we are rendering to an off-screen
+ // target.
if (showing_fullscreen_message_) {
// Message should display for 3 seconds after transition to fullscreen.
float elapsed_time =
@@ -1484,24 +1476,15 @@ void RendererD3D9::EndDraw() {
if (elapsed_time > display_duration) {
showing_fullscreen_message_ = false;
} else {
- ShowFullscreenMessage(elapsed_time, display_duration);
+ if (BeginDraw()) {
+ ShowFullscreenMessage(elapsed_time, display_duration);
+ EndDraw();
+ }
}
}
- HR(d3d_device_->EndScene());
-
- set_need_to_render(false);
-
- // Release the back-buffer references.
- back_buffer_surface_ = NULL;
- back_buffer_depth_surface_ = NULL;
- }
-}
-
-void RendererD3D9::FinishRendering() {
- // No need to call Present(...) if we are rendering to an off-screen
- // target.
- if (have_device_ && !off_screen_surface_ && !need_to_render()) {
- d3d_device_->Present(NULL, NULL, NULL, NULL);
+ if (!off_screen_surface_) {
+ d3d_device_->Present(NULL, NULL, NULL, NULL);
+ }
}
}
@@ -1511,7 +1494,7 @@ void RendererD3D9::RenderElement(Element* element,
Material* material,
ParamObject* override,
ParamCache* param_cache) {
- ++draw_elements_rendered_;
+ IncrementDrawElementsRendered();
// If this a new state then reset the old state.
State *current_state = material ? material->state() : NULL;
PushRenderStates(current_state);
@@ -1627,7 +1610,7 @@ RenderDepthStencilSurface::Ref RendererD3D9::CreateDepthStencilSurface(
depth_constructor));
}
-Bitmap::Ref RendererD3D9::TakeScreenshot() {
+Bitmap::Ref RendererD3D9::PlatformSpecificTakeScreenshot() {
Bitmap::Ref empty;
LPDIRECT3DDEVICE9 device = d3d_device();
CComPtr<IDirect3DSurface9> system_surface;
diff --git a/o3d/core/win/d3d9/renderer_d3d9.h b/o3d/core/win/d3d9/renderer_d3d9.h
index aa04490..37572c8 100644
--- a/o3d/core/win/d3d9/renderer_d3d9.h
+++ b/o3d/core/win/d3d9/renderer_d3d9.h
@@ -74,19 +74,6 @@ class RendererD3D9 : public Renderer {
// Released all hardware resources.
virtual void Destroy();
- // This method should be called before any draw calls take place in a
- // frame. It clears the back buffer, stencil and depth buffers.
- virtual bool BeginDraw();
-
- // Finalizes the drawing of the frame.
- virtual void EndDraw();
-
- // Does any pre-rendering preparation
- virtual bool StartRendering();
-
- // Presents the results of the draw calls for this frame.
- virtual void FinishRendering();
-
// Attempts to reset the back buffer to its new dimensions.
virtual void Resize(int width, int height);
@@ -156,9 +143,6 @@ class RendererD3D9 : public Renderer {
int width,
int height);
- // Overridden from Renderer.
- virtual Bitmap::Ref TakeScreenshot();
-
inline LPDIRECT3DDEVICE9 d3d_device() const { return d3d_device_; }
inline LPDIRECT3D9 d3d() const { return d3d_; }
@@ -175,6 +159,21 @@ class RendererD3D9 : public Renderer {
explicit RendererD3D9(ServiceLocator* service_locator);
// Overridden from Renderer.
+ virtual bool PlatformSpecificBeginDraw();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificEndDraw();
+
+ // Overridden from Renderer.
+ virtual bool PlatformSpecificStartRendering();
+
+ // Overridden from Renderer.
+ virtual void PlatformSpecificFinishRendering();
+
+ // Overridden from Renderer.
+ virtual Bitmap::Ref PlatformSpecificTakeScreenshot();
+
+ // Overridden from Renderer.
virtual ParamCache* CreatePlatformSpecificParamCache();
// Overridden from Renderer.
diff --git a/o3d/core/win/d3d9/texture_d3d9.cc b/o3d/core/win/d3d9/texture_d3d9.cc
index 3707c42..a352e98 100644
--- a/o3d/core/win/d3d9/texture_d3d9.cc
+++ b/o3d/core/win/d3d9/texture_d3d9.cc
@@ -175,21 +175,26 @@ class CubeFaceSurfaceConstructor : public SurfaceConstructor {
CubeFaceSurfaceConstructor(TextureCUBED3D9 *texture,
TextureCUBE::CubeFace face,
int mip_level)
- : cube_texture_(texture),
+ : cube_texture_(texture->GetWeakPointer()),
face_(face),
mip_level_(mip_level) {
}
virtual HRESULT ConstructSurface(IDirect3DSurface9** surface) {
+ TextureCUBED3D9* texture =
+ down_cast<TextureCUBED3D9*>(cube_texture_.Get());
+ if (!texture) {
+ return E_FAIL;
+ }
IDirect3DCubeTexture9* d3d_cube_texture =
- static_cast<IDirect3DCubeTexture9*>(cube_texture_->GetTextureHandle());
+ static_cast<IDirect3DCubeTexture9*>(texture->GetTextureHandle());
return d3d_cube_texture->GetCubeMapSurface(DX9CubeFace(face_),
mip_level_,
surface);
}
private:
- TextureCUBED3D9::Ref cube_texture_;
+ Texture::WeakPointerType cube_texture_;
TextureCUBE::CubeFace face_;
int mip_level_;
DISALLOW_COPY_AND_ASSIGN(CubeFaceSurfaceConstructor);
@@ -203,18 +208,22 @@ class CubeFaceSurfaceConstructor : public SurfaceConstructor {
class TextureSurfaceConstructor : public SurfaceConstructor {
public:
TextureSurfaceConstructor(Texture2DD3D9* texture, int mip_level)
- : texture_(texture),
+ : texture_(texture->GetWeakPointer()),
mip_level_(mip_level) {
}
virtual HRESULT ConstructSurface(IDirect3DSurface9** surface) {
+ Texture2DD3D9* texture = down_cast<Texture2DD3D9*>(texture_.Get());
+ if (!texture) {
+ return E_FAIL;
+ }
IDirect3DTexture9* d3d_texture =
- static_cast<IDirect3DTexture9*>(texture_->GetTextureHandle());
+ static_cast<IDirect3DTexture9*>(texture->GetTextureHandle());
return d3d_texture->GetSurfaceLevel(mip_level_, surface);
}
private:
- Texture2DD3D9::Ref texture_;
+ Texture::WeakPointerType texture_;
int mip_level_;
DISALLOW_COPY_AND_ASSIGN(TextureSurfaceConstructor);
};
@@ -265,7 +274,7 @@ void SetTextureRect(
DCHECK(src_data);
bool compressed = Texture::IsCompressedFormat(format);
- RECT rect = {dst_left, dst_top, src_width, src_height};
+ RECT rect = {dst_left, dst_top, dst_left + src_width, dst_top + src_height};
D3DLOCKED_RECT out_rect = {0};
if (!HR(d3d_texture->LockRect(
@@ -304,7 +313,7 @@ void SetTextureFaceRect(
DCHECK(src_data);
bool compressed = Texture::IsCompressedFormat(format);
- RECT rect = {dst_left, dst_top, src_width, src_height};
+ RECT rect = {dst_left, dst_top, dst_left + src_width, dst_top + src_height};
D3DLOCKED_RECT out_rect = {0};
D3DCUBEMAP_FACES d3d_face = DX9CubeFace(face);
@@ -391,7 +400,7 @@ Texture2DD3D9* Texture2DD3D9::Create(ServiceLocator* service_locator,
resize_to_pot,
enable_render_surfaces);
if (resize_to_pot) {
- texture->backing_bitmap_->Allocate(format, width, height, levels,
+ texture->backing_bitmap_->Allocate(format, width, height, levels,
Bitmap::IMAGE);
}
@@ -455,8 +464,8 @@ void Texture2DD3D9::UpdateBackedMipLevel(unsigned int level) {
}
}
-RenderSurface::Ref Texture2DD3D9::GetRenderSurface(int mip_level, Pack* pack) {
- DCHECK(pack);
+RenderSurface::Ref Texture2DD3D9::PlatformSpecificGetRenderSurface(
+ int mip_level) {
if (!render_surfaces_enabled()) {
O3D_ERROR(service_locator())
<< "Attempting to get RenderSurface from non-render-surface-enabled"
@@ -471,19 +480,13 @@ RenderSurface::Ref Texture2DD3D9::GetRenderSurface(int mip_level, Pack* pack) {
return RenderSurface::Ref(NULL);
}
- RenderSurface::Ref render_surface(
+ return RenderSurface::Ref(
new RenderSurfaceD3D9(
service_locator(),
width() >> mip_level,
height() >> mip_level,
this,
new TextureSurfaceConstructor(this, mip_level)));
-
- if (!render_surface.IsNull()) {
- RegisterSurface(render_surface.Get(), pack);
- }
-
- return render_surface;
}
void Texture2DD3D9::SetRect(int level,
@@ -571,16 +574,18 @@ bool Texture2DD3D9::Lock(int level, void** texture_data, int* pitch) {
<< "Attempting to lock a render-target texture: " << name();
return false;
}
+
+ unsigned int mip_width = image::ComputeMipDimension(level, width());
+ unsigned int mip_height = image::ComputeMipDimension(level, height());
+
if (resize_to_pot_) {
DCHECK(backing_bitmap_->image_data());
*texture_data = backing_bitmap_->GetMipData(level);
- unsigned int mip_width = image::ComputeMipDimension(level, width());
- unsigned int mip_height = image::ComputeMipDimension(level, height());
*pitch = image::ComputePitch(format(), mip_width);
locked_levels_ |= 1 << level;
return true;
} else {
- RECT rect = {0, 0, width(), height()};
+ RECT rect = {0, 0, mip_width, mip_height};
D3DLOCKED_RECT out_rect = {0};
if (HR(d3d_texture_->LockRect(level, &out_rect, &rect, 0))) {
@@ -793,9 +798,9 @@ void TextureCUBED3D9::UpdateBackedMipLevel(TextureCUBE::CubeFace face,
}
}
-RenderSurface::Ref TextureCUBED3D9::GetRenderSurface(TextureCUBE::CubeFace face,
- int mip_level,
- Pack* pack) {
+RenderSurface::Ref TextureCUBED3D9::PlatformSpecificGetRenderSurface(
+ TextureCUBE::CubeFace face,
+ int mip_level) {
if (!render_surfaces_enabled()) {
O3D_ERROR(service_locator())
<< "Attempting to get RenderSurface from non-render-surface-enabled"
@@ -811,19 +816,13 @@ RenderSurface::Ref TextureCUBED3D9::GetRenderSurface(TextureCUBE::CubeFace face,
}
int edge = edge_length() >> mip_level;
- RenderSurface::Ref render_surface(
+ return RenderSurface::Ref(
new RenderSurfaceD3D9(
service_locator(),
edge,
edge,
this,
new CubeFaceSurfaceConstructor(this, face, mip_level)));
-
- if (!render_surface.IsNull()) {
- RegisterSurface(render_surface.Get(), pack);
- }
-
- return render_surface;
}
void TextureCUBED3D9::SetRect(TextureCUBE::CubeFace face,
@@ -921,17 +920,19 @@ bool TextureCUBED3D9::Lock(
<< "Attempting to lock a render-target texture: " << name();
return false;
}
+
+ unsigned int mip_width = image::ComputeMipDimension(level, edge_length());
+ unsigned int mip_height = mip_width;
+
if (resize_to_pot_) {
Bitmap* backing_bitmap = backing_bitmaps_[face].Get();
DCHECK(backing_bitmap->image_data());
*texture_data = backing_bitmap->GetMipData(level);
- unsigned int mip_width = image::ComputeMipDimension(level, edge_length());
- unsigned int mip_height = mip_width;
*pitch = image::ComputePitch(format(), mip_width);
locked_levels_[face] |= 1 << level;
return true;
} else {
- RECT rect = {0, 0, edge_length(), edge_length()};
+ RECT rect = {0, 0, mip_width, mip_height};
D3DLOCKED_RECT out_rect = {0};
if (HR(d3d_cube_texture_->LockRect(DX9CubeFace(face), level,
diff --git a/o3d/core/win/d3d9/texture_d3d9.h b/o3d/core/win/d3d9/texture_d3d9.h
index 311f096..c8c948b 100644
--- a/o3d/core/win/d3d9/texture_d3d9.h
+++ b/o3d/core/win/d3d9/texture_d3d9.h
@@ -80,14 +80,6 @@ class Texture2DD3D9 : public Texture2D {
// Returns the implementation-specific texture handle for this texture.
virtual void* GetTextureHandle() const { return d3d_texture_; }
- // Returns a RenderSurface object associated with a mip_level of a texture.
- // Parameters:
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(int mip_level, Pack* pack);
-
// Handler for lost device. This invalidates the texture for a device reset.
bool OnLostDevice();
@@ -105,6 +97,9 @@ class Texture2DD3D9 : public Texture2D {
// Overridden from Texture2D
virtual bool Unlock(int level);
+ // Overridden from Texture2D
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(int mip_level);
+
private:
// Initializes the Texture2DD3D9 from a DX9 texture.
Texture2DD3D9(ServiceLocator* service_locator,
@@ -163,18 +158,6 @@ class TextureCUBED3D9 : public TextureCUBE {
// Returns the implementation-specific texture handle for this texture.
virtual void* GetTextureHandle() const { return d3d_cube_texture_; }
- // Returns a RenderSurface object associated with a given cube face and
- // mip_level of a texture.
- // Parameters:
- // face: [in] The cube face from which to extract the surface.
- // mip_level: [in] The mip-level of the surface to be returned.
- // pack: [in] The pack in which the surface will reside.
- // Returns:
- // Reference to the RenderSurface object.
- virtual RenderSurface::Ref GetRenderSurface(CubeFace face,
- int level,
- Pack* pack);
-
// Handler for lost device. This invalidates the texture for a device reset.
bool OnLostDevice();
@@ -192,6 +175,10 @@ class TextureCUBED3D9 : public TextureCUBE {
// Overridden from TextureCUBE
bool Unlock(CubeFace face, int level);
+ // Overridden from TextureCUBE.
+ virtual RenderSurface::Ref PlatformSpecificGetRenderSurface(CubeFace face,
+ int level);
+
private:
TextureCUBED3D9(ServiceLocator* service_locator,
IDirect3DCubeTexture9* tex,