Decouple EGLImageImage from ImageContainer. (bug 1222910, r=snorp)
authorDavid Anderson <danderson@mozilla.com>
Tue, 17 Nov 2015 00:09:00 -0800
changeset 272925 ff41eedeba3c18cc76984adef5f2dd9d04407304
parent 272924 ca5e17fccf13415d3efcb834211059fedaa576b6
child 272926 abd42e4c996d5303b78c4967a986c177acbb9258
push id29688
push userkwierso@gmail.com
push dateTue, 17 Nov 2015 21:10:09 +0000
treeherdermozilla-central@eed903a7e4e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1222910
milestone45.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
Decouple EGLImageImage from ImageContainer. (bug 1222910, r=snorp)
dom/media/platforms/android/AndroidDecoderModule.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
gfx/gl/GLBlitHelper.cpp
gfx/layers/GLImages.cpp
gfx/layers/GLImages.h
gfx/layers/ImageContainer.cpp
gfx/layers/ImageContainer.h
gfx/layers/client/ImageClient.cpp
gfx/layers/opengl/TextureClientOGL.cpp
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -151,26 +151,20 @@ public:
                                           LOCAL_EGL_SYNC_FENCE,
                                           nullptr);
         MOZ_ASSERT(eglSync);
         mGLContext->fFlush();
       } else {
         NS_WARNING("No EGL fence support detected, rendering artifacts may occur!");
       }
 
-      img = mImageContainer->CreateImage(ImageFormat::EGLIMAGE);
-      layers::EGLImageImage::Data data;
-      data.mImage = eglImage;
-      data.mSync = eglSync;
-      data.mOwns = true;
-      data.mSize = mConfig.mDisplay;
-      data.mOriginPos = gl::OriginPos::TopLeft;
-
-      layers::EGLImageImage* typedImg = static_cast<layers::EGLImageImage*>(img.get());
-      typedImg->SetData(data);
+      img = new layers::EGLImageImage(
+        eglImage, eglSync,
+        mConfig.mDisplay, gl::OriginPos::TopLeft,
+        true /* owns */);
     }
 
     nsresult rv;
     int32_t flags;
     NS_ENSURE_SUCCESS(rv = aInfo->Flags(&flags), rv);
 
     bool isSync = !!(flags & MediaCodec::BUFFER_FLAG_SYNC_FRAME);
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -174,26 +174,20 @@ AttachToContainerAsEGLImage(ImageContain
   MOZ_ASSERT(out_image);
   MOZ_ASSERT(!*out_image);
 
   EGLImage image = instance->AsEGLImage();
   if (!image) {
     return;
   }
 
-  RefPtr<Image> img = container->CreateImage(ImageFormat::EGLIMAGE);
-
-  EGLImageImage::Data data;
-  data.mImage = image;
-  data.mSize = gfx::IntSize(rect.width, rect.height);
-  data.mOriginPos = instance->OriginPos();
-
-  EGLImageImage* typedImg = static_cast<EGLImageImage*>(img.get());
-  typedImg->SetData(data);
-
+  RefPtr<EGLImageImage> img = new EGLImageImage(
+    image, nullptr,
+    gfx::IntSize(rect.width, rect.height), instance->OriginPos(),
+    false /* owns */);
   *out_image = img;
 }
 
 static void
 AttachToContainerAsSurfaceTexture(ImageContainer* container,
                                   nsNPAPIPluginInstance* instance,
                                   const LayoutDeviceRect& rect,
                                   RefPtr<Image>* out_image)
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -708,18 +708,18 @@ GLBlitHelper::BlitSurfaceTextureImage(la
 
     mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
     return true;
 }
 
 bool
 GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image)
 {
-    EGLImage eglImage = image->GetData()->mImage;
-    EGLSync eglSync = image->GetData()->mSync;
+    EGLImage eglImage = image->GetImage();
+    EGLSync eglSync = image->GetSync();
 
     if (eglSync) {
         EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER);
         if (status != LOCAL_EGL_CONDITION_SATISFIED) {
             return false;
         }
     }
 
@@ -842,17 +842,17 @@ GLBlitHelper::BlitImageToFramebuffer(lay
     case ImageFormat::SURFACE_TEXTURE:
         type = ConvertSurfaceTexture;
         srcOrigin = static_cast<layers::SurfaceTextureImage*>(srcImage)->GetData()
                                                                        ->mOriginPos;
         break;
 
     case ImageFormat::EGLIMAGE:
         type = ConvertEGLImage;
-        srcOrigin = static_cast<layers::EGLImageImage*>(srcImage)->GetData()->mOriginPos;
+        srcOrigin = srcImage->AsEGLImageImage()->GetOriginPos();
         break;
 #endif
 #ifdef XP_MACOSX
     case ImageFormat::MAC_IOSURFACE:
         type = ConvertMacIOSurfaceImage;
         srcOrigin = OriginPos::TopLeft;
         break;
 #endif
--- a/gfx/layers/GLImages.cpp
+++ b/gfx/layers/GLImages.cpp
@@ -11,30 +11,42 @@
 using namespace mozilla;
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 static RefPtr<GLContext> sSnapshotContext;
 
+EGLImageImage::EGLImageImage(EGLImage aImage, EGLSync aSync,
+                             const gfx::IntSize& aSize, const gl::OriginPos& aOrigin,
+                             bool aOwns)
+ : GLImage(ImageFormat::EGLIMAGE),
+   mImage(aImage),
+   mSync(aSync),
+   mSize(aSize),
+   mPos(aOrigin),
+   mOwns(aOwns)
+{
+}
+
 EGLImageImage::~EGLImageImage()
 {
-  if (!mData.mOwns) {
+  if (!mOwns) {
     return;
   }
 
-  if (mData.mImage) {
-    sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mData.mImage);
-    mData.mImage = nullptr;
+  if (mImage) {
+    sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mImage);
+    mImage = nullptr;
   }
 
-  if (mData.mSync) {
-    sEGLLibrary.fDestroySync(EGL_DISPLAY(), mData.mSync);
-    mData.mSync = nullptr;
+  if (mSync) {
+    sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSync);
+    mSync = nullptr;
   }
 }
 
 already_AddRefed<gfx::SourceSurface>
 GLImage::GetAsSourceSurface()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
 
--- a/gfx/layers/GLImages.h
+++ b/gfx/layers/GLImages.h
@@ -23,41 +23,44 @@ class GLImage : public Image {
 public:
   explicit GLImage(ImageFormat aFormat) : Image(nullptr, aFormat){}
 
   virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
 };
 
 class EGLImageImage : public GLImage {
 public:
-  struct Data {
-    EGLImage mImage;
-    EGLSync mSync;
-    gfx::IntSize mSize;
-    gl::OriginPos mOriginPos;
-    bool mOwns;
+  EGLImageImage(EGLImage aImage, EGLSync aSync,
+                const gfx::IntSize& aSize, const gl::OriginPos& aOrigin,
+                bool aOwns);
 
-    Data() : mImage(nullptr), mSync(nullptr), mSize(0, 0),
-             mOriginPos(gl::OriginPos::TopLeft), mOwns(false)
-    {
-    }
-  };
+  gfx::IntSize GetSize() override { return mSize; }
+  gl::OriginPos GetOriginPos() const {
+    return mPos;
+  }
+  EGLImage GetImage() const {
+    return mImage;
+  }
+  EGLSync GetSync() const {
+    return mSync;
+  }
 
-  void SetData(const Data& aData) { mData = aData; }
-  const Data* GetData() { return &mData; }
-
-  gfx::IntSize GetSize() { return mData.mSize; }
-
-  EGLImageImage() : GLImage(ImageFormat::EGLIMAGE) {}
+  EGLImageImage* AsEGLImageImage() override {
+    return this;
+  }
 
 protected:
   virtual ~EGLImageImage();
 
 private:
-  Data mData;
+  EGLImage mImage;
+  EGLSync mSync;
+  gfx::IntSize mSize;
+  gl::OriginPos mPos;
+  bool mOwns;
 };
 
 #ifdef MOZ_WIDGET_ANDROID
 
 class SurfaceTextureImage : public GLImage {
 public:
   struct Data {
     mozilla::gl::AndroidSurfaceTexture* mSurfTex;
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -76,20 +76,16 @@ ImageFactory::CreateImage(ImageFormat aF
     return img.forget();
   }
 #ifdef MOZ_WIDGET_ANDROID
   if (aFormat == ImageFormat::SURFACE_TEXTURE) {
     img = new SurfaceTextureImage();
     return img.forget();
   }
 #endif
-  if (aFormat == ImageFormat::EGLIMAGE) {
-    img = new EGLImageImage();
-    return img.forget();
-  }
 #ifdef XP_MACOSX
   if (aFormat == ImageFormat::MAC_IOSURFACE) {
     img = new MacIOSurfaceImage();
     return img.forget();
   }
 #endif
   return nullptr;
 }
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -110,16 +110,19 @@ class GrallocImage;
 struct ImageBackendData
 {
   virtual ~ImageBackendData() {}
 
 protected:
   ImageBackendData() {}
 };
 
+/* Forward declarations for Image derivatives. */
+class EGLImageImage;
+
 /**
  * A class representing a buffer of pixel data. The data can be in one
  * of various formats including YCbCr.
  * 
  * Create an image using an ImageContainer. Fill the image with data, and
  * then call ImageContainer::SetImage to display it. An image must not be
  * modified after calling SetImage. Image implementations do not need to
  * perform locking; when filling an Image, the Image client is responsible
@@ -156,21 +159,24 @@ public:
     return nullptr;
   }
 
   virtual bool IsValid() { return true; }
 
   virtual uint8_t* GetBuffer() { return nullptr; }
 
   /**
-  * For use with the CompositableClient only (so that the later can
-  * synchronize the TextureClient with the TextureHost).
-  */
+   * For use with the CompositableClient only (so that the later can
+   * synchronize the TextureClient with the TextureHost).
+   */
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) { return nullptr; }
 
+  /* Access to derived classes. */
+  virtual EGLImageImage* AsEGLImageImage() { return nullptr; }
+
 protected:
   Image(void* aImplData, ImageFormat aFormat) :
     mImplData(aImplData),
     mSerial(++sSerialCounter),
     mFormat(aFormat)
   {}
 
   // Protected destructor, to discourage deletion outside of Release():
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -199,17 +199,17 @@ ImageClientSingle::UpdateImage(ImageCont
         if (!status) {
           return false;
         }
       } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE ||
                  image->GetFormat() == ImageFormat::EGLIMAGE) {
         gfx::IntSize size = image->GetSize();
 
         if (image->GetFormat() == ImageFormat::EGLIMAGE) {
-          EGLImageImage* typedImage = static_cast<EGLImageImage*>(image);
+          EGLImageImage* typedImage = image->AsEGLImageImage();
           texture = new EGLImageTextureClient(GetForwarder(),
                                               mTextureFlags,
                                               typedImage,
                                               size);
 #ifdef MOZ_WIDGET_ANDROID
         } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
           SurfaceTextureImage* typedImage = static_cast<SurfaceTextureImage*>(image);
           const SurfaceTextureImage::Data* data = typedImage->GetData();
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -29,31 +29,32 @@ EGLImageTextureClient::EGLImageTextureCl
   , mSize(aSize)
   , mIsLocked(false)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
              "Can't pass an `EGLImage` between processes.");
 
   AddFlags(TextureFlags::DEALLOCATE_CLIENT);
 
-  if (aImage->GetData()->mOriginPos == gl::OriginPos::BottomLeft) {
+  if (aImage->GetOriginPos() == gl::OriginPos::BottomLeft) {
     AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
   }
 }
 
 bool
 EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
   MOZ_ASSERT(IsValid());
   MOZ_ASSERT(IsAllocated());
 
-  const EGLImageImage::Data* data = mImage->GetData();
   const bool hasAlpha = true;
-  aOutDescriptor = EGLImageDescriptor((uintptr_t)data->mImage, (uintptr_t)data->mSync,
-                                      mSize, hasAlpha);
+  aOutDescriptor =
+    EGLImageDescriptor((uintptr_t)mImage->GetImage(),
+                       (uintptr_t)mImage->GetSync(),
+                       mImage->GetSize(), hasAlpha);
   return true;
 }
 
 bool
 EGLImageTextureClient::Lock(OpenMode mode)
   {
     MOZ_ASSERT(!mIsLocked);
     if (!IsValid() || !IsAllocated()) {