Bug 1176024 - Have TextureClient::Lock check that it can expose a DrawTarget when it makes sense. r=Bas
authorNicolas Silva <nsilva@mozilla.com>
Wed, 30 Dec 2015 13:23:01 +0100
changeset 277887 fcd8d385410805aa3fadc7f027c478f65cda7dbc
parent 277886 ee4446a2c02a04f6fba9c6ba573ab45445997277
child 277888 350fbdbad784715d2e36a4dcb3eb7d89002033e2
push id69630
push usernsilva@mozilla.com
push dateWed, 30 Dec 2015 12:23:13 +0000
treeherdermozilla-inbound@fcd8d3854108 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1176024
milestone46.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 1176024 - Have TextureClient::Lock check that it can expose a DrawTarget when it makes sense. r=Bas
gfx/layers/client/TextureClient.cpp
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -358,16 +358,34 @@ TextureClient::Lock(OpenMode aMode)
   if (mRemoveFromCompositableWaiter) {
     mRemoveFromCompositableWaiter->WaitComplete();
     mRemoveFromCompositableWaiter = nullptr;
   }
 
   mIsLocked = mData->Lock(aMode, mReleaseFenceHandle.IsValid() ? &mReleaseFenceHandle : nullptr);
   mOpenMode = aMode;
 
+  auto format = GetFormat();
+  if (mIsLocked && CanExposeDrawTarget() &&
+      aMode == OpenMode::OPEN_READ_WRITE &&
+      NS_IsMainThread() &&
+      // the formats that we apparently expect, in the cairo backend. Any other
+      // format will trigger an assertion in GfxFormatToCairoFormat.
+      (format == SurfaceFormat::A8R8G8B8_UINT32 ||
+      format == SurfaceFormat::X8R8G8B8_UINT32 ||
+      format == SurfaceFormat::A8 ||
+      format == SurfaceFormat::R5G6B5_UINT16)) {
+    if (!BorrowDrawTarget()) {
+      // Failed to get a DrawTarget, means we won't be able to write into the
+      // texture, might as well fail now.
+      Unlock();
+      return false;
+    }
+  }
+
   return mIsLocked;
 }
 
 void
 TextureClient::Unlock()
 {
   MOZ_ASSERT(IsValid());
   MOZ_ASSERT(mIsLocked);
@@ -422,16 +440,19 @@ TextureClient::~TextureClient()
 }
 
 void
 TextureClient::UpdateFromSurface(gfx::SourceSurface* aSurface)
 {
   MOZ_ASSERT(IsValid());
   MOZ_ASSERT(mIsLocked);
   MOZ_ASSERT(aSurface);
+  // If you run into this assertion, make sure the texture was locked write-only
+  // rather than read-write.
+  MOZ_ASSERT(!mBorrowedDrawTarget);
 
   // XXX - It would be better to first try the DrawTarget approach and fallback
   // to the backend-specific implementation because the latter will usually do
   // an expensive read-back + cpu-side copy if the texture is on the gpu.
   // There is a bug with the DrawTarget approach, though specific to reading back
   // from WebGL (where R and B channel end up inverted) to figure out first.
   if (mData->UpdateFromSurface(aSurface)) {
     return;