Back out bug 1421313 because of build breakage on a CLOSED TREE r=me
authorJames Willcox <snorp@snorp.net>
Wed, 06 Dec 2017 09:52:30 -0600
changeset 708635 06f2b3ee174ee56ef7e65d12e00dcfe4fd1e39b8
parent 708634 1e136e8cc9a55350e5f811a9ae2f767918770344
child 708636 5c23693e39ed774721a9a2f276984a4bac6ed615
push id92403
push userVYV03354@nifty.ne.jp
push dateWed, 06 Dec 2017 22:18:41 +0000
reviewersme
bugs1421313
milestone59.0a1
Back out bug 1421313 because of build breakage on a CLOSED TREE r=me MozReview-Commit-ID: HhNuCAUDU59
gfx/layers/LayerScope.cpp
gfx/layers/moz.build
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/TexturePoolOGL.cpp
gfx/layers/opengl/TexturePoolOGL.h
gfx/thebes/gfxPlatform.cpp
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -9,16 +9,17 @@
 
 #include "nsAppRunner.h"
 #include "Effects.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TimeStamp.h"
 
+#include "TexturePoolOGL.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/TextureHostOGL.h"
 
 #include "gfxContext.h"
 #include "gfxUtils.h"
 #include "gfxPrefs.h"
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -36,16 +36,17 @@ EXPORTS += [
     'Layers.h',
     'LayerScope.h',
     'LayersLogging.h',
     'LayerSorter.h',
     'LayersTypes.h',
     'LayerTreeInvalidation.h',
     'LayerUserData.h',
     'opengl/OGLShaderProgram.h',
+    'opengl/TexturePoolOGL.h',
     'protobuf/LayerScopePacket.pb.h',
     'ReadbackLayer.h',
     'TiledLayerBuffer.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'D3D11ShareHandleImage.cpp',
@@ -447,16 +448,17 @@ UNIFIED_SOURCES += [
     'mlgpu/TexturedLayerMLGPU.cpp',
     'mlgpu/TextureSourceProviderMLGPU.cpp',
     'opengl/CompositingRenderTargetOGL.cpp',
     'opengl/CompositorOGL.cpp',
     'opengl/GLBlitTextureImageHelper.cpp',
     'opengl/OGLShaderProgram.cpp',
     'opengl/TextureClientOGL.cpp',
     'opengl/TextureHostOGL.cpp',
+    'opengl/TexturePoolOGL.cpp',
     'PaintThread.cpp',
     'ReadbackProcessor.cpp',
     'RenderTrace.cpp',
     'RotatedBuffer.cpp',
     'ShareableCanvasRenderer.cpp',
     'SourceSurfaceSharedData.cpp',
     'SourceSurfaceVolatileData.cpp',
     'SyncObject.cpp',
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -41,16 +41,17 @@
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsString, nsAutoCString, etc
 #include "ScopedGLHelpers.h"
 #include "GLReadTexImageHelper.h"
 #include "GLBlitTextureImageHelper.h"
 #include "HeapCopyOfStackArray.h"
 
 #if MOZ_WIDGET_ANDROID
+#include "TexturePoolOGL.h"
 #include "GeneratedJNIWrappers.h"
 #endif
 
 #include "GeckoProfiler.h"
 
 namespace mozilla {
 
 using namespace std;
@@ -668,16 +669,17 @@ CompositorOGL::BeginFrame(const nsIntReg
   } else {
     MakeCurrent();
   }
 
   mPixelsPerFrame = width * height;
   mPixelsFilled = 0;
 
 #ifdef MOZ_WIDGET_ANDROID
+  TexturePoolOGL::Fill(gl());
   java::GeckoSurfaceTexture::DestroyUnused((int64_t)mGLContext.get());
 #endif
 
   // Default blend function implements "OVER"
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA);
   mGLContext->fEnable(LOCAL_GL_BLEND);
 
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/TexturePoolOGL.cpp
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TexturePoolOGL.h"
+#include <stdlib.h>                     // for malloc
+#include "GLContext.h"                  // for GLContext
+#include "mozilla/Logging.h"
+#include "mozilla/Monitor.h"            // for Monitor, MonitorAutoLock
+#include "mozilla/mozalloc.h"           // for operator delete, etc
+#include "mozilla/layers/CompositorThread.h"
+#include "nsDebug.h"                    // for NS_ASSERTION, NS_ERROR, etc
+#include "nsDeque.h"                    // for nsDeque
+#include "nsThreadUtils.h"
+
+static const unsigned int TEXTURE_POOL_SIZE = 10;
+static const unsigned int TEXTURE_REFILL_THRESHOLD = TEXTURE_POOL_SIZE / 2;
+
+static mozilla::LazyLogModule gTexturePoolLog("TexturePoolOGL");
+#define LOG(arg, ...) MOZ_LOG(gTexturePoolLog, mozilla::LogLevel::Debug, ("TexturePoolOGL::%s: " arg, __func__, ##__VA_ARGS__))
+
+namespace mozilla {
+namespace gl {
+
+static GLContext* sActiveContext = nullptr;
+
+static Monitor* sMonitor = nullptr;
+static nsDeque* sTextures = nullptr;
+
+enum class PoolState : uint8_t {
+  NOT_INITIALIZE,
+  INITIALIZED,
+  SHUTDOWN
+};
+static PoolState sPoolState = PoolState::NOT_INITIALIZE;
+
+static bool sHasPendingFillTask = false;
+
+void TexturePoolOGL::MaybeFillTextures()
+{
+  if (sTextures->GetSize() < TEXTURE_REFILL_THRESHOLD &&
+      !sHasPendingFillTask) {
+    LOG("need to refill the texture pool.");
+    sHasPendingFillTask = true;
+    MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
+    MOZ_ASSERT(loop);
+    loop->PostTask(
+      NS_NewRunnableFunction(
+        "TexturePoolOGL::MaybeFillTextures",
+        [] () {
+          TexturePoolOGL::Fill(sActiveContext);
+    }));
+  }
+}
+
+GLuint TexturePoolOGL::AcquireTexture()
+{
+  MOZ_ASSERT(sPoolState != PoolState::NOT_INITIALIZE, "not initialized");
+  MOZ_ASSERT(sPoolState != PoolState::SHUTDOWN, "should not be called after shutdown");
+
+  MonitorAutoLock lock(*sMonitor);
+
+  if (!sActiveContext) {
+    // Wait for a context
+    sMonitor->Wait();
+
+    if (!sActiveContext)
+      return 0;
+  }
+
+  GLuint texture = 0;
+  if (sActiveContext->IsOwningThreadCurrent()) {
+    sActiveContext->MakeCurrent();
+
+    sActiveContext->fGenTextures(1, &texture);
+  } else {
+    while (sTextures->GetSize() == 0) {
+      NS_WARNING("Waiting for texture");
+      sMonitor->Wait();
+    }
+
+    GLuint* popped = (GLuint*) sTextures->Pop();
+    if (!popped) {
+      NS_ERROR("Failed to pop texture pool item");
+      return 0;
+    }
+
+    texture = *popped;
+    delete popped;
+
+    NS_ASSERTION(texture, "Failed to retrieve texture from pool");
+
+    MaybeFillTextures();
+    LOG("remaining textures num = %zu", sTextures->GetSize());
+  }
+
+  return texture;
+}
+
+static void Clear()
+{
+  const bool isCurrent = sActiveContext && sActiveContext->MakeCurrent();
+
+  GLuint* item;
+  while (sTextures->GetSize()) {
+    item = (GLuint*)sTextures->Pop();
+    if (isCurrent) {
+      sActiveContext->fDeleteTextures(1, item);
+    }
+    delete item;
+  }
+}
+
+void TexturePoolOGL::Fill(GLContext* aContext)
+{
+  MOZ_ASSERT(aContext, "NULL GLContext");
+  MOZ_ASSERT(sPoolState != PoolState::NOT_INITIALIZE, "not initialized");
+  MOZ_ASSERT(sPoolState != PoolState::SHUTDOWN, "should not be called after shutdown");
+
+  MonitorAutoLock lock(*sMonitor);
+  sHasPendingFillTask = false;
+
+  if (sActiveContext != aContext) {
+    Clear();
+    sActiveContext = aContext;
+  }
+
+  if (sTextures->GetSize() == TEXTURE_POOL_SIZE)
+    return;
+
+  DebugOnly<bool> ok = sActiveContext->MakeCurrent();
+  MOZ_ASSERT(ok);
+
+  GLuint* texture = nullptr;
+  while (sTextures->GetSize() < TEXTURE_POOL_SIZE) {
+    texture = (GLuint*)malloc(sizeof(GLuint));
+    sActiveContext->fGenTextures(1, texture);
+    sTextures->Push((void*) texture);
+  }
+
+  LOG("fill texture pool to %d", TEXTURE_POOL_SIZE);
+  sMonitor->NotifyAll();
+}
+
+GLContext* TexturePoolOGL::GetGLContext()
+{
+  return sActiveContext;
+}
+
+void TexturePoolOGL::Init()
+{
+  MOZ_ASSERT(sPoolState != PoolState::INITIALIZED);
+  sMonitor = new Monitor("TexturePoolOGL.sMonitor");
+  sTextures = new nsDeque();
+
+  sPoolState = PoolState::INITIALIZED;
+}
+
+void TexturePoolOGL::Shutdown()
+{
+  MOZ_ASSERT(sPoolState == PoolState::INITIALIZED);
+  sPoolState = PoolState::SHUTDOWN;
+  delete sMonitor;
+  delete sTextures;
+}
+
+} // namespace gl
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/TexturePoolOGL.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GFX_TEXTUREPOOLOGL_H
+#define GFX_TEXTUREPOOLOGL_H
+
+#include "GLContextTypes.h"             // for GLContext, GLuint
+
+namespace mozilla {
+namespace gl {
+
+// A texture pool for for the on-screen GLContext. The main purpose of this class
+// is to provide the ability to easily allocate an on-screen texture from the
+// content thread. The unfortunate nature of the SurfaceTexture API (see AndroidSurfaceTexture)
+// necessitates this.
+class TexturePoolOGL
+{
+public:
+  // Get a new texture from the pool. Will block
+  // and wait for one to be created if necessary
+  static GLuint AcquireTexture();
+
+  // Called by the active LayerManagerOGL to fill
+  // the pool
+  static void Fill(GLContext* aContext);
+
+  static GLContext* GetGLContext();
+
+  // Initializes the pool, but does not fill it. Called by gfxPlatform init.
+  static void Init();
+
+  // Clears all internal data structures in preparation for shutdown
+  static void Shutdown();
+private:
+  // These methods are used to refill textures to avoid pool becomes dry
+  static void MaybeFillTextures();
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GFX_TEXTUREPOOLOGL_H
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -87,16 +87,20 @@
 #include "imgITools.h"
 
 #include "plstr.h"
 #include "nsCRT.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "mozilla/gfx/Logging.h"
 
+#ifdef MOZ_WIDGET_ANDROID
+#include "TexturePoolOGL.h"
+#endif
+
 #ifdef USE_SKIA
 # ifdef __GNUC__
 #  pragma GCC diagnostic push
 #  pragma GCC diagnostic ignored "-Wshadow"
 # endif
 # include "skia/include/core/SkGraphics.h"
 # ifdef USE_SKIA_GPU
 #  include "skia/include/gpu/GrContext.h"
@@ -811,16 +815,21 @@ gfxPlatform::Init()
     gPlatform->mSRGBOverrideObserver = new SRGBOverrideObserver();
     Preferences::AddWeakObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
 
     gPlatform->mFontPrefsObserver = new FontPrefsObserver();
     Preferences::AddStrongObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
 
     GLContext::PlatformStartup();
 
+#ifdef MOZ_WIDGET_ANDROID
+    // Texture pool init
+    TexturePoolOGL::Init();
+#endif
+
     Preferences::RegisterCallbackAndCall(RecordingPrefChanged, "gfx.2d.recording");
 
     CreateCMSOutputProfile();
 
     // Listen to memory pressure event so we can purge DrawTarget caches
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
         gPlatform->mMemoryPressureObserver = new MemoryPressureObserver();
@@ -963,16 +972,21 @@ gfxPlatform::Shutdown()
     gPlatform->mSkiaGlue = nullptr;
 
     if (XRE_IsParentProcess()) {
       gPlatform->mVsyncSource->Shutdown();
     }
 
     gPlatform->mVsyncSource = nullptr;
 
+#ifdef MOZ_WIDGET_ANDROID
+    // Shut down the texture pool
+    TexturePoolOGL::Shutdown();
+#endif
+
     // Shut down the default GL context provider.
     GLContextProvider::Shutdown();
 
 #if defined(XP_WIN)
     // The above shutdown calls operate on the available context providers on
     // most platforms.  Windows is a "special snowflake", though, and has three
     // context providers available, so we have to shut all of them down.
     // We should only support the default GL provider on Windows; then, this