diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-25 00:18:47 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-25 00:18:47 +0000 |
commit | 2976fe30ed9e0454b0995456e64a5ef7ae216df8 (patch) | |
tree | 5194cf65778a90b5a277df3d635b8164da39bb50 /o3d/core | |
parent | c874da66d375909e04eb2a0aba669b162c41faba (diff) | |
download | chromium_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.cc | 40 | ||||
-rw-r--r-- | o3d/core/cross/client.h | 3 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/renderer_cb.cc | 42 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/renderer_cb.h | 30 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/texture_cb.cc | 9 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/texture_cb.h | 26 | ||||
-rw-r--r-- | o3d/core/cross/gl/renderer_gl.cc | 38 | ||||
-rw-r--r-- | o3d/core/cross/gl/renderer_gl.h | 32 | ||||
-rw-r--r-- | o3d/core/cross/gl/texture_gl.cc | 27 | ||||
-rw-r--r-- | o3d/core/cross/gl/texture_gl.h | 26 | ||||
-rw-r--r-- | o3d/core/cross/pack_test.cc | 27 | ||||
-rw-r--r-- | o3d/core/cross/renderer.cc | 70 | ||||
-rw-r--r-- | o3d/core/cross/renderer.h | 113 | ||||
-rw-r--r-- | o3d/core/cross/texture.cc | 28 | ||||
-rw-r--r-- | o3d/core/cross/texture.h | 24 | ||||
-rw-r--r-- | o3d/core/cross/texture_base.cc | 6 | ||||
-rw-r--r-- | o3d/core/cross/texture_base.h | 2 | ||||
-rw-r--r-- | o3d/core/win/d3d9/renderer_d3d9.cc | 77 | ||||
-rw-r--r-- | o3d/core/win/d3d9/renderer_d3d9.h | 31 | ||||
-rw-r--r-- | o3d/core/win/d3d9/texture_d3d9.cc | 69 | ||||
-rw-r--r-- | o3d/core/win/d3d9/texture_d3d9.h | 27 |
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, |