Bug 960254: Implement the new Map/Unmap API for Direct2D. r=jrmuizel
☠☠ backed out by 2628e64cf375 ☠ ☠
authorBas Schouten <bschouten@mozilla.com>
Thu, 16 Jan 2014 13:17:24 +0100
changeset 163690 4aecc5ca2a19bdc70bde8389cf0d13e2f430c24d
parent 163689 9f499e5f7954989f095a949c7bd8d70955501860
child 163691 4441c32c724c6bb40a02312d1eba5295fd2686d4
push id38542
push userbschouten@mozilla.com
push dateThu, 16 Jan 2014 12:17:56 +0000
treeherdermozilla-inbound@4aecc5ca2a19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs960254
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 960254: Implement the new Map/Unmap API for Direct2D. r=jrmuizel
gfx/2d/SourceSurfaceD2D.cpp
gfx/2d/SourceSurfaceD2D.h
gfx/2d/SourceSurfaceD2D1.cpp
gfx/2d/SourceSurfaceD2D1.h
gfx/2d/SourceSurfaceD2DTarget.cpp
gfx/2d/SourceSurfaceD2DTarget.h
--- a/gfx/2d/SourceSurfaceD2D.cpp
+++ b/gfx/2d/SourceSurfaceD2D.cpp
@@ -169,17 +169,17 @@ DataSourceSurfaceD2D::DataSourceSurfaceD
 
   renderTarget->BeginDraw();
   renderTarget->DrawBitmap(aSourceSurface->mBitmap,
                            D2D1::RectF(0, 0,
                                        Float(mSize.width),
                                        Float(mSize.height)));
   renderTarget->EndDraw();
 
-  desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
+  desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
   desc.Usage = D3D10_USAGE_STAGING;
   desc.BindFlags = 0;
   hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create staging texture. Code: " << hr;
     mTexture = nullptr;
     return;
   }
@@ -223,19 +223,66 @@ DataSourceSurfaceD2D::GetSize() const
 }
 
 SurfaceFormat
 DataSourceSurfaceD2D::GetFormat() const
 {
   return mFormat;
 }
 
+bool
+DataSourceSurfaceD2D::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  if (!mTexture) {
+    return false;
+  }
+
+  D3D10_MAP mapType;
+
+  if (aMapType == MapType::READ) {
+    mapType = D3D10_MAP_READ;
+  } else if (aMapType == MapType::WRITE) {
+    mapType = D3D10_MAP_WRITE;
+  } else {
+    mapType = D3D10_MAP_READ_WRITE;
+  }
+
+  D3D10_MAPPED_TEXTURE2D map;
+
+  HRESULT hr = mTexture->Map(0, mapType, 0, &map);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Texture map failed with code: " << hr;
+    return false;
+  }
+
+  aMappedSurface->mData = (uint8_t*)map.pData;
+  aMappedSurface->mStride = map.RowPitch;
+
+  return true;
+}
+
+void
+DataSourceSurfaceD2D::Unmap()
+{
+  MOZ_ASSERT(mIsMapped);
+
+  mTexture->Unmap(0);
+}
+
 void
 DataSourceSurfaceD2D::EnsureMappedTexture()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
+
   if (mMapped ||
       !mTexture) {
     return;
   }
 
   HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mData);
   if (FAILED(hr)) {
     gfxWarning() << "Failed to map texture. Code: " << hr;
--- a/gfx/2d/SourceSurfaceD2D.h
+++ b/gfx/2d/SourceSurfaceD2D.h
@@ -57,16 +57,18 @@ class DataSourceSurfaceD2D : public Data
 public:
   DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface);
   virtual ~DataSourceSurfaceD2D();
 
   virtual unsigned char* GetData();
   virtual int32_t Stride();
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
   bool IsValid()
   {
     return mTexture;
   }
 
 private:
   void EnsureMappedTexture();
--- a/gfx/2d/SourceSurfaceD2D1.cpp
+++ b/gfx/2d/SourceSurfaceD2D1.cpp
@@ -136,27 +136,58 @@ DataSourceSurfaceD2D1::GetSize() const
 uint8_t*
 DataSourceSurfaceD2D1::GetData()
 {
   EnsureMapped();
 
   return mMap.bits;
 }
 
+bool
+DataSourceSurfaceD2D1::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  D2D1_MAP_OPTIONS options;
+  if (aMapType == MapType::READ) {
+    options = D2D1_MAP_OPTIONS_READ;
+  } else {
+    MOZ_CRASH("No support for Write maps on D2D1 DataSourceSurfaces yet!");
+  }
+
+  D2D1_MAPPED_RECT map;
+  mBitmap->Map(D2D1_MAP_OPTIONS_READ, &map);
+  aMappedSurface->mData = map.bits;
+  aMappedSurface->mStride = map.pitch;
+
+  mIsMapped = true;
+  return true;
+}
+
+void
+DataSourceSurfaceD2D1::Unmap()
+{
+  mBitmap->Unmap();
+}
+
 int32_t
 DataSourceSurfaceD2D1::Stride()
 {
   EnsureMapped();
 
   return mMap.pitch;
 }
 
 void
 DataSourceSurfaceD2D1::EnsureMapped()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
   if (mMapped) {
     return;
   }
   mBitmap->Map(D2D1_MAP_OPTIONS_READ, &mMap);
   mMapped = true;
 }
 
 }
--- a/gfx/2d/SourceSurfaceD2D1.h
+++ b/gfx/2d/SourceSurfaceD2D1.h
@@ -65,16 +65,18 @@ public:
   DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat);
   ~DataSourceSurfaceD2D1();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
   virtual uint8_t *GetData();
   virtual int32_t Stride();
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
 private:
   friend class SourceSurfaceD2DTarget;
   void EnsureMapped();
 
   mutable RefPtr<ID2D1Bitmap1> mBitmap;
   SurfaceFormat mFormat;
   D2D1_MAPPED_RECT mMap;
--- a/gfx/2d/SourceSurfaceD2DTarget.cpp
+++ b/gfx/2d/SourceSurfaceD2DTarget.cpp
@@ -231,19 +231,65 @@ DataSourceSurfaceD2DTarget::GetData()
 
 int32_t
 DataSourceSurfaceD2DTarget::Stride()
 {
   EnsureMapped();
   return mMap.RowPitch;
 }
 
+bool
+DataSourceSurfaceD2DTarget::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  if (!mTexture) {
+    return false;
+  }
+
+  D3D10_MAP mapType;
+
+  if (aMapType == MapType::READ) {
+    mapType = D3D10_MAP_READ;
+  } else if (aMapType == MapType::WRITE) {
+    mapType = D3D10_MAP_WRITE;
+  } else {
+    mapType = D3D10_MAP_READ_WRITE;
+  }
+
+  D3D10_MAPPED_TEXTURE2D map;
+
+  HRESULT hr = mTexture->Map(0, mapType, 0, &map);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Texture map failed with code: " << hr;
+    return false;
+  }
+
+  aMappedSurface->mData = (uint8_t*)map.pData;
+  aMappedSurface->mStride = map.RowPitch;
+
+  return true;
+}
+
+void
+DataSourceSurfaceD2DTarget::Unmap()
+{
+  MOZ_ASSERT(mIsMapped);
+
+  mTexture->Unmap(0);
+}
+
 void
 DataSourceSurfaceD2DTarget::EnsureMapped()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
   if (!mMapped) {
     HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
     if (FAILED(hr)) {
       gfxWarning() << "Failed to map texture to memory. Code: " << hr;
       return;
     }
     mMapped = true;
   }
--- a/gfx/2d/SourceSurfaceD2DTarget.h
+++ b/gfx/2d/SourceSurfaceD2DTarget.h
@@ -63,16 +63,18 @@ public:
   DataSourceSurfaceD2DTarget(SurfaceFormat aFormat);
   ~DataSourceSurfaceD2DTarget();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual uint8_t *GetData();
   virtual int32_t Stride();
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
 private:
   friend class SourceSurfaceD2DTarget;
   void EnsureMapped();
 
   mutable RefPtr<ID3D10Texture2D> mTexture;
   SurfaceFormat mFormat;
   D3D10_MAPPED_TEXTURE2D mMap;