Bug 960254 - Part 4: Implement the new Map/Unmap API for Direct2D. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Thu, 16 Jan 2014 13:17:24 +0100
changeset 163792 327d381e24c82ab621dd7e01200121aa8de7eaef
parent 163791 bbad01205856e33a3271f74980200b7b841095a4
child 163793 3ea3277ce769950b6ec1af6b159cc6c73ee15a7b
push id26011
push userryanvm@gmail.com
push dateThu, 16 Jan 2014 20:06:29 +0000
treeherdermozilla-central@bcbe93f41547 [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 - Part 4: 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;