diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-11 18:12:50 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-11 18:12:50 +0000 |
commit | ed97932b6ec58d01baea6948d5506503247f2986 (patch) | |
tree | 19ae1cfc4de8ce29ba75ab0386d1f56a1bacf57a /o3d/core/win | |
parent | f963b1d5006ed35450befe042bf58810d9d36bea (diff) | |
download | chromium_src-ed97932b6ec58d01baea6948d5506503247f2986.zip chromium_src-ed97932b6ec58d01baea6948d5506503247f2986.tar.gz chromium_src-ed97932b6ec58d01baea6948d5506503247f2986.tar.bz2 |
Changes to Bitmap before exposing to JavaScript
This CL changes Bitmap to no longer be a cubemap.
Instead there is a function, Pack::CreateBitmapsFromRawData
that returns an array of bitmaps.
For a 2D image 1 bitmap is returned
For a cubemap 6 bitmaps are returned
eventually for a volumemap N bitmaps will be returned.
To distinguish between 6 bitmaps that are a cubemap
and 6 bitmaps that are slices of a volumemap there
is a Bitmap::semantic which tells what the bitmap is
intended for.
In a previous CL I had started to break Bitmap into
classes like Bitmap8, BitmapFloat, BitmapDXT1.
These were not intended to be exposed to JavaScript,
only to make the internal code get rid of lots of
if format == or case(format) stuff.
But given that it's working as is and there are more
pressing things I'm not planning to do that right now.
I can delete the classes if you think I should.
Note: This is still not 100% done. I still need to
deal with the flipping issues or at least test.
I probably need to add more tests as well.
I also got rid of any mention of resize_to_pot in
the command buffer version. Client side command
buffer should not have to deal with POT/NPOT issues.
I also moved the pot/npot stuff out of generic code
and into the platform specific code. The generic code
is not supposed to care.
This is slower than the old way but it feels cleaner.
A few issues I'm looking for input on. There's
a function, Bitmap::GenerateMips(source_level, num_levels).
It generates mips as long as they 8Bit textures.
I can easily add half and float but not DXT. Right now
if you call it on DXT in debug it prints a LOG message
but otherwise it does nothing. Should I error for DXT?
On the one hand it would be good to know that it failed
so a user will not be wondering "I called it, why are
there no mips?"
On the otherhand, from JavaScript failing would mean
you'd need to check the format before calling it which
also seems less then ideal.
The other is that currently it doesn't ADD mips, it just
replaces the ones that are there. That means if you load
a 2d image and want mips you have to allocate a new bitmap
with the number of mips you want, copy level 0 from the
old bitmap to the new bitmap and then generate mips
Should I make generate mips effectively do that for you?
Basically, if you call it to generate mips on levels
that don't yet exist in the bitmap it would realloc itself
and then generate them. Is that better?
Also, I started down the path of taking out alpha_is_one.
I'm trying to decide what to do with it. Part of me wants
to take it out completely but since it's already there
maybe I can't.
If I leave it in I was thinking of making it check every
time it's called. First I'd just make it slow. Then later
if we want I could add a dirty flag and only recheck when
it's dirty. That would be a lot of work though. It would
mean wrapping Lock and SetRect and maybe a few other things
so that we could catch any writes to the texture. It might
also mean changing Lock to take read/write flags. I think
those are good changes but again, it's not important right
now. So, the question is what to do now. I can
1) Remove alpha_is_one. That might break something out there
2) Leave it in but just have it always false.
3) Make it check every time it's accessed.
4) Do the dirty flag thing.
Preference? I'm for 2 or 3 I think.
Review URL: http://codereview.chromium.org/164235
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23051 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/core/win')
-rw-r--r-- | o3d/core/win/d3d9/renderer_d3d9.cc | 48 | ||||
-rw-r--r-- | o3d/core/win/d3d9/renderer_d3d9.h | 3 | ||||
-rw-r--r-- | o3d/core/win/d3d9/texture_d3d9.cc | 179 | ||||
-rw-r--r-- | o3d/core/win/d3d9/texture_d3d9.h | 30 |
4 files changed, 126 insertions, 134 deletions
diff --git a/o3d/core/win/d3d9/renderer_d3d9.cc b/o3d/core/win/d3d9/renderer_d3d9.cc index 035f615..29142eb 100644 --- a/o3d/core/win/d3d9/renderer_d3d9.cc +++ b/o3d/core/win/d3d9/renderer_d3d9.cc @@ -1606,30 +1606,6 @@ ParamCache* RendererD3D9::CreatePlatformSpecificParamCache() { return new ParamCacheD3D9(service_locator()); } -// Attempts to create a Texture with the given bitmap, automatically -// determining whether the to create a 2D texture, cube texture, etc. If -// creation fails the method returns NULL. -// Parameters: -// bitmap: The bitmap specifying the dimensions, format and content of the -// new texture. The created texture takes ownership of the bitmap -// data. -// Returns: -// A ref-counted pointer to the texture or NULL if it did not load. -Texture::Ref RendererD3D9::CreatePlatformSpecificTextureFromBitmap( - Bitmap* bitmap) { - if (bitmap->is_cubemap()) { - return Texture::Ref(TextureCUBED3D9::Create(service_locator(), - bitmap, - this, - false)); - } else { - return Texture::Ref(Texture2DD3D9::Create(service_locator(), - bitmap, - this, - false)); - } -} - // Attempts to create a Texture2D with the given specs. If creation fails // then the method returns NULL. Texture2D::Ref RendererD3D9::CreatePlatformSpecificTexture2D( @@ -1638,32 +1614,26 @@ Texture2D::Ref RendererD3D9::CreatePlatformSpecificTexture2D( Texture::Format format, int levels, bool enable_render_surfaces) { - Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); - bitmap->set_format(format); - bitmap->set_width(width); - bitmap->set_height(height); - bitmap->set_num_mipmaps(levels); return Texture2D::Ref(Texture2DD3D9::Create(service_locator(), - bitmap, + format, + levels, + width, + height, this, enable_render_surfaces)); } -// Attempts to create a Texture2D with the given specs. If creation fails +// Attempts to create a TextureCUBE with the given specs. If creation fails // then the method returns NULL. TextureCUBE::Ref RendererD3D9::CreatePlatformSpecificTextureCUBE( int edge_length, Texture::Format format, int levels, bool enable_render_surfaces) { - Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); - bitmap->set_format(format); - bitmap->set_width(edge_length); - bitmap->set_height(edge_length); - bitmap->set_num_mipmaps(levels); - bitmap->set_is_cubemap(true); return TextureCUBE::Ref(TextureCUBED3D9::Create(service_locator(), - bitmap, + format, + levels, + edge_length, this, enable_render_surfaces)); } @@ -1744,7 +1714,7 @@ Bitmap::Ref RendererD3D9::TakeScreenshot() { surface_description.Width, surface_description.Height, 1, - false); + Bitmap::IMAGE); bitmap->SetRect(0, 0, 0, surface_description.Width, surface_description.Height, diff --git a/o3d/core/win/d3d9/renderer_d3d9.h b/o3d/core/win/d3d9/renderer_d3d9.h index f81a6c7..7d6f9bb 100644 --- a/o3d/core/win/d3d9/renderer_d3d9.h +++ b/o3d/core/win/d3d9/renderer_d3d9.h @@ -194,9 +194,6 @@ class RendererD3D9 : public Renderer { float max_z); // Overridden from Renderer. - virtual Texture::Ref CreatePlatformSpecificTextureFromBitmap(Bitmap* bitmap); - - // Overridden from Renderer. virtual Texture2D::Ref CreatePlatformSpecificTexture2D( int width, int height, diff --git a/o3d/core/win/d3d9/texture_d3d9.cc b/o3d/core/win/d3d9/texture_d3d9.cc index 5c93f7b..13c3d3b 100644 --- a/o3d/core/win/d3d9/texture_d3d9.cc +++ b/o3d/core/win/d3d9/texture_d3d9.cc @@ -82,20 +82,23 @@ static D3DCUBEMAP_FACES DX9CubeFace(TextureCUBE::CubeFace face) { return D3DCUBEMAP_FACE_FORCE_DWORD; } -// Constructs an Direct3D texture object. Out variable return the status of +// Constructs an Direct3D texture object. Out variable returns the status of // the constructed texture including if resize to POT is required, and the // actual mip dimensions used. HRESULT CreateTexture2DD3D9(RendererD3D9* renderer, - Bitmap* bitmap, + Texture::Format format, + int levels, + int width, + int height, bool enable_render_surfaces, bool* resize_to_pot, unsigned int* mip_width, unsigned int* mip_height, IDirect3DTexture9** d3d_texture) { IDirect3DDevice9 *d3d_device = renderer->d3d_device(); - *resize_to_pot = !renderer->supports_npot() && !bitmap->IsPOT(); - *mip_width = bitmap->width(); - *mip_height = bitmap->height(); + *resize_to_pot = !renderer->supports_npot() && !image::IsPOT(width, height); + *mip_width = width; + *mip_height = height; if (*resize_to_pot) { *mip_width = image::ComputePOTSize(*mip_width); @@ -104,56 +107,59 @@ HRESULT CreateTexture2DD3D9(RendererD3D9* renderer, DWORD usage = (enable_render_surfaces) ? D3DUSAGE_RENDERTARGET : 0; D3DPOOL pool = (enable_render_surfaces) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; - D3DFORMAT format = DX9Format(bitmap->format()); + D3DFORMAT d3d_format = DX9Format(format); HRESULT tex_result = d3d_device->CreateTexture(*mip_width, *mip_height, - bitmap->num_mipmaps(), + levels, usage, - format, + d3d_format, pool, d3d_texture, NULL); if (!HR(tex_result)) { DLOG(ERROR) << "2D texture creation failed with the following parameters: " << "(" << *mip_width << " x " << *mip_height << ") x " - << bitmap->num_mipmaps() << "; format = " << format; + << levels << "; format = " << format; } return tex_result; } -// Constructs an Direct3D cube texture object. Out variable return the +// Constructs an Direct3D cube texture object. Out variable returns the // status of the constructed texture including if resize to POT is required, // and the actual mip edge length used. HRESULT CreateTextureCUBED3D9(RendererD3D9* renderer, - Bitmap* bitmap, + int edge_length, + Texture::Format format, + int levels, bool enable_render_surfaces, bool* resize_to_pot, unsigned int* edge_width, IDirect3DCubeTexture9** d3d_texture) { IDirect3DDevice9 *d3d_device = renderer->d3d_device(); - *resize_to_pot = !renderer->supports_npot() && !bitmap->IsPOT(); - *edge_width = bitmap->width(); + *resize_to_pot = !renderer->supports_npot() && + !image::IsPOT(edge_length, edge_length); + *edge_width = edge_length; if (*resize_to_pot) { *edge_width = image::ComputePOTSize(*edge_width); } DWORD usage = (enable_render_surfaces) ? D3DUSAGE_RENDERTARGET : 0; D3DPOOL pool = (enable_render_surfaces) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; - D3DFORMAT format = DX9Format(bitmap->format()); + D3DFORMAT d3d_format = DX9Format(format); HRESULT tex_result = d3d_device->CreateCubeTexture(*edge_width, - bitmap->num_mipmaps(), + levels, usage, - format, + d3d_format, pool, d3d_texture, NULL); if (!HR(tex_result)) { DLOG(ERROR) << "CUBE texture creation failed with the following " << "parameters: " - << "(" << edge_width << " x " << edge_width << ") x " - << bitmap->num_mipmaps() << "; format = " << format; + << "(" << *edge_width << " x " << *edge_width << ") x " + << levels << "; format = " << format; } return tex_result; @@ -329,17 +335,19 @@ void SetTextureFaceRect( // Constructs a 2D texture object from the given (existing) D3D 2D texture. Texture2DD3D9::Texture2DD3D9(ServiceLocator* service_locator, IDirect3DTexture9* tex, - const Bitmap &bitmap, + Texture::Format format, + int levels, + int width, + int height, bool resize_to_pot, bool enable_render_surfaces) : Texture2D(service_locator, - bitmap.width(), - bitmap.height(), - bitmap.format(), - bitmap.num_mipmaps(), - bitmap.CheckAlphaIsOne(), - resize_to_pot, + width, + height, + format, + levels, enable_render_surfaces), + resize_to_pot_(resize_to_pot), d3d_texture_(tex), backing_bitmap_(Bitmap::Ref(new Bitmap(service_locator))) { DCHECK(tex); @@ -350,16 +358,21 @@ Texture2DD3D9::Texture2DD3D9(ServiceLocator* service_locator, // returns it. This is the safe way to create a Texture2DD3D9 object that // contains a valid D3D9 texture. Texture2DD3D9* Texture2DD3D9::Create(ServiceLocator* service_locator, - Bitmap* bitmap, + Texture::Format format, + int levels, + int width, + int height, RendererD3D9* renderer, bool enable_render_surfaces) { - DCHECK_NE(bitmap->format(), Texture::UNKNOWN_FORMAT); - DCHECK(!bitmap->is_cubemap()); + DCHECK_NE(format, Texture::UNKNOWN_FORMAT); CComPtr<IDirect3DTexture9> d3d_texture; bool resize_to_pot; unsigned int mip_width, mip_height; if (!HR(CreateTexture2DD3D9(renderer, - bitmap, + format, + levels, + width, + height, enable_render_surfaces, &resize_to_pot, &mip_width, @@ -371,23 +384,14 @@ Texture2DD3D9* Texture2DD3D9::Create(ServiceLocator* service_locator, Texture2DD3D9 *texture = new Texture2DD3D9(service_locator, d3d_texture, - *bitmap, + format, + levels, + width, + height, resize_to_pot, enable_render_surfaces); - - texture->backing_bitmap_->SetFrom(bitmap); - if (texture->backing_bitmap_->image_data()) { - for (unsigned int i = 0; i < bitmap->num_mipmaps(); ++i) { - texture->UpdateBackedMipLevel(i); - mip_width = std::max(1U, mip_width >> 1); - mip_height = std::max(1U, mip_height >> 1); - } - if (!resize_to_pot) - texture->backing_bitmap_->FreeData(); - } else { - if (resize_to_pot) { - texture->backing_bitmap_->AllocateData(); - } + if (resize_to_pot) { + texture->backing_bitmap_->AllocateData(); } return texture; @@ -637,7 +641,10 @@ bool Texture2DD3D9::OnResetDevice() { bool resize_to_pot; unsigned int mip_width, mip_height; return HR(CreateTexture2DD3D9(renderer_d3d9, - backing_bitmap_, + format(), + levels(), + width(), + height(), render_surfaces_enabled(), &resize_to_pot, &mip_width, @@ -654,36 +661,42 @@ const Texture::RGBASwizzleIndices& Texture2DD3D9::GetABGR32FSwizzleIndices() { // Constructs a cube texture object from the given (existing) D3D Cube texture. TextureCUBED3D9::TextureCUBED3D9(ServiceLocator* service_locator, IDirect3DCubeTexture9* tex, - const Bitmap& bitmap, + int edge_length, + Texture::Format format, + int levels, bool resize_to_pot, bool enable_render_surfaces) : TextureCUBE(service_locator, - bitmap.width(), - bitmap.format(), - bitmap.num_mipmaps(), - bitmap.CheckAlphaIsOne(), - resize_to_pot, + edge_length, + format, + levels, enable_render_surfaces), - d3d_cube_texture_(tex), - backing_bitmap_(Bitmap::Ref(new Bitmap(service_locator))) { + resize_to_pot_(resize_to_pot), + d3d_cube_texture_(tex) { + for (int ii = 0; ii < static_cast<int>(NUMBER_OF_FACES); ++ii) { + backing_bitmaps_[ii] = Bitmap::Ref(new Bitmap(service_locator)); + } } // Attempts to create a D3D9 CubeTexture with the given specs. If creation // fails the method returns NULL. Otherwise, it wraps around the newly created // texture a TextureCUBED3D9 object and returns a pointer to it. TextureCUBED3D9* TextureCUBED3D9::Create(ServiceLocator* service_locator, - Bitmap *bitmap, + Texture::Format format, + int levels, + int edge_length, RendererD3D9 *renderer, bool enable_render_surfaces) { - DCHECK_NE(bitmap->format(), Texture::UNKNOWN_FORMAT); - DCHECK(bitmap->is_cubemap()); - DCHECK_EQ(bitmap->width(), bitmap->height()); + DCHECK_NE(format, Texture::UNKNOWN_FORMAT); + DCHECK_GE(levels, 1); CComPtr<IDirect3DCubeTexture9> d3d_texture; bool resize_to_pot; unsigned int edge; if (!HR(CreateTextureCUBED3D9(renderer, - bitmap, + edge_length, + format, + levels, enable_render_surfaces, &resize_to_pot, &edge, @@ -694,24 +707,14 @@ TextureCUBED3D9* TextureCUBED3D9::Create(ServiceLocator* service_locator, TextureCUBED3D9 *texture = new TextureCUBED3D9(service_locator, d3d_texture, - *bitmap, + edge_length, + format, + levels, resize_to_pot, enable_render_surfaces); - - texture->backing_bitmap_->SetFrom(bitmap); - if (texture->backing_bitmap_->image_data()) { - for (int face = 0; face < 6; ++face) { - unsigned int mip_edge = edge; - for (unsigned int i = 0; i < bitmap->num_mipmaps(); ++i) { - texture->UpdateBackedMipLevel(static_cast<CubeFace>(face), i); - mip_edge = std::max(1U, mip_edge >> 1); - } - } - if (!resize_to_pot) - texture->backing_bitmap_->FreeData(); - } else { - if (resize_to_pot) { - texture->backing_bitmap_->AllocateData(); + if (resize_to_pot) { + for (int ii = 0; ii < static_cast<int>(NUMBER_OF_FACES); ++ii) { + texture->backing_bitmaps_[ii]->AllocateData(); } } @@ -735,13 +738,13 @@ TextureCUBED3D9::~TextureCUBED3D9() { void TextureCUBED3D9::UpdateBackedMipLevel(TextureCUBE::CubeFace face, unsigned int level) { + Bitmap* backing_bitmap = backing_bitmaps_[face].Get(); DCHECK_LT(level, static_cast<unsigned int>(levels())); - DCHECK(backing_bitmap_->image_data()); - DCHECK(backing_bitmap_->is_cubemap()); - DCHECK_EQ(backing_bitmap_->width(), edge_length()); - DCHECK_EQ(backing_bitmap_->height(), edge_length()); - DCHECK_EQ(backing_bitmap_->format(), format()); - DCHECK_EQ(backing_bitmap_->num_mipmaps(), levels()); + DCHECK(backing_bitmap->image_data()); + DCHECK_EQ(backing_bitmap->width(), edge_length()); + DCHECK_EQ(backing_bitmap->height(), edge_length()); + DCHECK_EQ(backing_bitmap->format(), format()); + DCHECK_EQ(backing_bitmap->num_mipmaps(), levels()); unsigned int mip_edge = std::max(1, edge_length() >> level); unsigned int rect_edge = mip_edge; @@ -762,7 +765,7 @@ void TextureCUBED3D9::UpdateBackedMipLevel(TextureCUBE::CubeFace face, DCHECK(out_rect.pBits); uint8* dst = static_cast<uint8*>(out_rect.pBits); - const uint8 *mip_data = backing_bitmap_->GetFaceMipData(face, level); + const uint8 *mip_data = backing_bitmap->GetMipData(level); if (resize_to_pot_) { image::Scale(mip_edge, mip_edge, format(), mip_data, rect_edge, rect_edge, @@ -870,11 +873,12 @@ void TextureCUBED3D9::SetRect(TextureCUBE::CubeFace face, } if (resize_to_pot_) { - DCHECK(backing_bitmap_->image_data()); + Bitmap* backing_bitmap = backing_bitmaps_[face].Get(); + DCHECK(backing_bitmap->image_data()); DCHECK(!compressed); // We need to update the backing mipmap and then use that to update the // texture. - backing_bitmap_->SetFaceRect(face, + backing_bitmap->SetRect( level, dst_left, dst_top, src_width, src_height, src_data, src_pitch); UpdateBackedMipLevel(face, level); } else { @@ -916,8 +920,9 @@ bool TextureCUBED3D9::Lock( return false; } if (resize_to_pot_) { - DCHECK(backing_bitmap_->image_data()); - *texture_data = backing_bitmap_->GetFaceMipData(face, level); + 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); @@ -988,7 +993,9 @@ bool TextureCUBED3D9::OnResetDevice() { bool resize_to_pot; unsigned int mip_edge; return HR(CreateTextureCUBED3D9(renderer_d3d9, - backing_bitmap_, + edge_length(), + format(), + levels(), render_surfaces_enabled(), &resize_to_pot, &mip_edge, diff --git a/o3d/core/win/d3d9/texture_d3d9.h b/o3d/core/win/d3d9/texture_d3d9.h index 5f10951..311f096 100644 --- a/o3d/core/win/d3d9/texture_d3d9.h +++ b/o3d/core/win/d3d9/texture_d3d9.h @@ -59,7 +59,10 @@ class Texture2DD3D9 : public Texture2D { // creation fails then it returns NULL otherwise it returns a pointer to the // newly created Texture object. static Texture2DD3D9* Create(ServiceLocator* service_locator, - Bitmap* bitmap, + Texture::Format format, + int levels, + int width, + int height, RendererD3D9* renderer, bool enable_render_surfaces); @@ -106,7 +109,10 @@ class Texture2DD3D9 : public Texture2D { // Initializes the Texture2DD3D9 from a DX9 texture. Texture2DD3D9(ServiceLocator* service_locator, IDirect3DTexture9* tex, - const Bitmap& bitmap, + Texture::Format format, + int levels, + int width, + int height, bool resize_to_pot, bool enable_render_surfaces); @@ -114,6 +120,10 @@ class Texture2DD3D9 : public Texture2D { // rescaling it if resize_to_pot_ is set. void UpdateBackedMipLevel(unsigned int level); + // Whether or not this texture needs to be resized from NPOT to pot behind + // the scenes. + bool resize_to_pot_; + // A pointer to the Direct3D 2D texture object containing this texture. CComPtr<IDirect3DTexture9> d3d_texture_; @@ -132,7 +142,9 @@ class TextureCUBED3D9 : public TextureCUBE { // creation fails then it returns NULL otherwise it returns a pointer to the // newly created Texture object. static TextureCUBED3D9* Create(ServiceLocator* service_locator, - Bitmap* bitmap, + Texture::Format format, + int levels, + int edge_length, RendererD3D9* renderer, bool enable_render_surfaces); @@ -183,10 +195,16 @@ class TextureCUBED3D9 : public TextureCUBE { private: TextureCUBED3D9(ServiceLocator* service_locator, IDirect3DCubeTexture9* tex, - const Bitmap& bitmap, + int edge_length, + Texture::Format format, + int levels, bool resize_to_pot, bool enable_render_surfaces); + // Whether or not this texture needs to be resized from NPOT to pot behind + // the scenes. + bool resize_to_pot_; + // Updates a mip level, sending it from the backing bitmap to Direct3D, // rescaling it if resize_to_pot_ is set. void UpdateBackedMipLevel(CubeFace face, unsigned int level); @@ -194,8 +212,8 @@ class TextureCUBED3D9 : public TextureCUBE { // A pointer to the Direct3D cube texture object containing this texture. CComPtr<IDirect3DCubeTexture9> d3d_cube_texture_; - // A bitmap used to back the NPOT textures on POT-only hardware. - Bitmap::Ref backing_bitmap_; + // Bitmaps used to back the NPOT textures on POT-only hardware. + Bitmap::Ref backing_bitmaps_[NUMBER_OF_FACES]; DISALLOW_COPY_AND_ASSIGN(TextureCUBED3D9); }; |