Bug 595180: Draw window resizer on Mac OS X. r=joe r=josh a=blocking2.0beta9+
authorMarkus Stange <mstange@themasta.com>
Fri, 07 Jan 2011 15:32:42 -0500
changeset 60224 8d005c3a66857951a71e2fd84e9cb8eb71c88cc4
parent 60223 dc0cff820b221e5bc517d77a2372800a0236144b
child 60225 7558dc118df513a41cbed1da33027eea0d09a87f
push id17886
push userjosh@mozilla.com
push dateFri, 07 Jan 2011 20:45:43 +0000
treeherdermozilla-central@8d005c3a6685 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe, josh, blocking2.0beta9
bugs595180
milestone2.0b9pre
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 595180: Draw window resizer on Mac OS X. r=joe r=josh a=blocking2.0beta9+
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGLProgram.h
gfx/thebes/GLContext.h
widget/public/nsIWidget.h
widget/src/cocoa/nsChildView.h
widget/src/cocoa/nsChildView.mm
widget/src/cocoa/nsCocoaWindow.h
widget/src/cocoa/nsCocoaWindow.mm
widget/src/xpwidgets/nsBaseWidget.h
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -61,17 +61,19 @@
 
 #include "nsIGfxInfo.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gl;
 
+#ifdef CHECK_CURRENT_PROGRAM
 int LayerManagerOGLProgram::sCurrentProgramKey = 0;
+#endif
 
 /**
  * LayerManagerOGL
  */
 LayerManagerOGL::LayerManagerOGL(nsIWidget *aWidget)
   : mWidget(aWidget)
   , mWidgetSize(-1, -1)
   , mBackBufferFBO(0)
@@ -593,16 +595,18 @@ LayerManagerOGL::Render()
   DEBUG_GL_ERROR_CHECK(mGLContext);
 
   mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
   mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
 
   // Render our layers.
   RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() && !mTarget ? 0 : mBackBufferFBO,
                            nsIntPoint(0, 0));
+                           
+  static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(mWidget)->DrawOver(this, rect);
 
   DEBUG_GL_ERROR_CHECK(mGLContext);
 
   if (mTarget) {
     CopyToTarget();
     return;
   }
 
--- a/gfx/layers/opengl/LayerManagerOGLProgram.h
+++ b/gfx/layers/opengl/LayerManagerOGLProgram.h
@@ -43,21 +43,26 @@
 #include "prenv.h"
 
 #include "nsString.h"
 #include "GLContext.h"
 
 namespace mozilla {
 namespace layers {
 
+#if defined(DEBUG) && defined(MOZ_ENABLE_LIBXUL)
+#define CHECK_CURRENT_PROGRAM 1
 #define ASSERT_THIS_PROGRAM                                             \
   do {                                                                  \
     NS_ASSERTION(mGL->GetUserData(&sCurrentProgramKey) == this, \
                  "SetUniform with wrong program active!");              \
   } while (0)
+#else
+#define ASSERT_THIS_PROGRAM
+#endif
 
 struct UniformValue {
   UniformValue() {
     memset(this, 0, sizeof(UniformValue));
   }
 
   void setInt(const int i) {
     value.i[0] = i;
@@ -100,17 +105,19 @@ struct UniformValue {
   union {
     int i[1];
     float f[16];
   } value;
 };
 
 class LayerManagerOGLProgram {
 protected:
+#ifdef CHECK_CURRENT_PROGRAM
   static int sCurrentProgramKey;
+#endif
 
 public:
   typedef mozilla::gl::GLContext GLContext;
 
   // common attrib locations
   enum {
     VertexAttrib = 0,
     TexCoordAttrib = 1
@@ -127,17 +134,19 @@ public:
     }
     ctx->MakeCurrent();
     ctx->fDeleteProgram(mProgram);
   }
 
   void Activate() {
     NS_ASSERTION(mProgram != 0, "Attempting to activate a program that's not in use!");
     mGL->fUseProgram(mProgram);
+#if CHECK_CURRENT_PROGRAM
     mGL->SetUserData(&sCurrentProgramKey, this);
+#endif
   }
 
   void SetUniform(GLuint aUniform, float aFloatValue) {
     ASSERT_THIS_PROGRAM;
 
     if (aUniform == GLuint(-1))
       return;
 
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -772,16 +772,29 @@ public:
      */
     ShaderProgramType UploadSurfaceToTexture(gfxASurface *aSurface, 
                                              const nsIntRect& aSrcRect,
                                              GLuint& aTexture,
                                              bool aOverwrite = false,
                                              const nsIntPoint& aDstPoint = nsIntPoint(0, 0),
                                              bool aPixelBuffer = PR_FALSE);
 
+#ifndef MOZ_ENABLE_LIBXUL
+    virtual ShaderProgramType UploadSurfaceToTextureExternal(gfxASurface *aSurface, 
+                                                             const nsIntRect& aSrcRect,
+                                                             GLuint& aTexture,
+                                                             bool aOverwrite = false,
+                                                             const nsIntPoint& aDstPoint = nsIntPoint(0, 0),
+                                                             bool aPixelBuffer = PR_FALSE)
+    {
+      return UploadSurfaceToTexture(aSurface, aSrcRect, aTexture, aOverwrite,
+                                    aDstPoint, aPixelBuffer);
+    }
+#endif
+
     /** Helper for DecomposeIntoNoRepeatTriangles
      */
     struct RectTriangles {
         RectTriangles() : numRects(0) { }
 
         void addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
                      GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1);
 
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -1394,13 +1394,21 @@ class nsIWidget_MOZILLA_2_0_BRANCH : pub
     };
 
     virtual LayerManager *GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull) = 0;
 
     // Hide build warnings about nsIWidget::GetLayerManager being hidden by
     // our GetLayerManager method above.
     using nsIWidget::GetLayerManager;
+
+    /**
+     * Called after the LayerManager draws the layer tree
+     *
+     * @param aManager The drawing LayerManager.
+     * @param aRect Current widget rect that is being drawn.
+     */
+    virtual void DrawOver(LayerManager* aManager, nsIntRect aRect) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget_MOZILLA_2_0_BRANCH, NS_IWIDGET_MOZILLA_2_0_BRANCH_IID)
 
 #endif // nsIWidget_h__
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -388,16 +388,17 @@ public:
   
   virtual PRBool    DispatchWindowEvent(nsGUIEvent& event);
   
 #ifdef ACCESSIBILITY
   already_AddRefed<nsAccessible> GetDocumentAccessible();
 #endif
 
   virtual gfxASurface* GetThebesSurface();
+  virtual void DrawOver(LayerManager* aManager, nsIntRect aRect);
 
   NS_IMETHOD BeginSecureKeyboardInput();
   NS_IMETHOD EndSecureKeyboardInput();
 
   void              HidePlugin();
   void              UpdatePluginPort();
 
   void              ResetParent();
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -2072,16 +2072,25 @@ nsChildView::GetThebesSurface()
 {
   if (!mTempThebesSurface) {
     mTempThebesSurface = new gfxQuartzSurface(gfxSize(1, 1), gfxASurface::ImageFormatARGB32);
   }
 
   return mTempThebesSurface;
 }
 
+void
+nsChildView::DrawOver(LayerManager* aManager, nsIntRect aRect)
+{
+  nsCocoaWindow *cocoaWindow = GetXULWindowWidget();
+  if (cocoaWindow) {
+    cocoaWindow->DrawOver(aManager, aRect);
+  }
+}
+
 NS_IMETHODIMP
 nsChildView::BeginSecureKeyboardInput()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsresult rv = nsBaseWidget::BeginSecureKeyboardInput();
   if (NS_SUCCEEDED(rv))
     ::EnableSecureEventInput();
--- a/widget/src/cocoa/nsCocoaWindow.h
+++ b/widget/src/cocoa/nsCocoaWindow.h
@@ -274,16 +274,17 @@ public:
     virtual void SetDrawsInTitlebar(PRBool aState);
     virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
                                                 PRUint32 aNativeMessage,
                                                 PRUint32 aModifierFlags);
 
     void DispatchSizeModeEvent();
 
     virtual gfxASurface* GetThebesSurface();
+    virtual void DrawOver(LayerManager* aManager, nsIntRect aRect);
 
     // be notified that a some form of drag event needs to go into Gecko
     virtual PRBool DragEvent(unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers);
 
     PRBool HasModalDescendents() { return mNumModalDescendents > 0; }
     NSWindow *GetCocoaWindow() { return mWindow; }
 
     void SetMenuBar(nsMenuBarX* aMenuBar);
--- a/widget/src/cocoa/nsCocoaWindow.mm
+++ b/widget/src/cocoa/nsCocoaWindow.mm
@@ -66,22 +66,27 @@
 #include "nsStyleConsts.h"
 #include "nsNativeThemeColors.h"
 #include "nsChildView.h"
 #include "nsIMenuRollup.h"
 
 #include "gfxPlatform.h"
 #include "qcms.h"
 
+#include "GLContext.h"
+#include "LayerManagerOGL.h"
+#include "gfxQuartzSurface.h"
+
 namespace mozilla {
 namespace layers {
 class LayerManager;
 }
 }
 using namespace mozilla::layers;
+using namespace mozilla::gl;
 
 // defined in nsAppShell.mm
 extern nsCocoaAppModalWindowList *gCocoaAppModalWindowList;
 
 PRInt32 gXULModalLevel = 0;
 
 // In principle there should be only one app-modal window at any given time.
 // But sometimes, despite our best efforts, another window appears above the
@@ -936,16 +941,89 @@ LayerManager*
 nsCocoaWindow::GetLayerManager(LayerManagerPersistence, bool* aAllowRetaining)
 {
   if (mPopupContentView) {
     return mPopupContentView->GetLayerManager(aAllowRetaining);
   }
   return nsnull;
 }
 
+void
+nsCocoaWindow::DrawOver(LayerManager* aManager, nsIntRect aRect)
+{
+  if (!([mWindow styleMask] & NSResizableWindowMask)) {
+    return;
+  }
+
+  nsRefPtr<LayerManagerOGL> manager(static_cast<LayerManagerOGL*>(aManager));
+  if (!manager) {
+    return;
+  }
+  
+  float bottomX = aRect.x + aRect.width;
+  float bottomY = aRect.y + aRect.height;
+
+  nsRefPtr<gfxQuartzSurface> image =
+    new gfxQuartzSurface(gfxIntSize(15, 15), gfxASurface::ImageFormatARGB32);
+  CGContextRef ctx = image->GetCGContext();
+
+  CGContextSetShouldAntialias(ctx, false);
+  CGPoint points[6];
+  points[0] = CGPointMake(13.0f, 4.0f);
+  points[1] = CGPointMake(3.0f, 14.0f);
+  points[2] = CGPointMake(13.0f, 8.0f);
+  points[3] = CGPointMake(7.0f, 14.0f);
+  points[4] = CGPointMake(13.0f, 12.0f);
+  points[5] = CGPointMake(11.0f, 14.0f);
+  CGContextSetRGBStrokeColor(ctx, 0.00f, 0.00f, 0.00f, 0.15f);
+  CGContextStrokeLineSegments(ctx, points, 6);
+
+  points[0] = CGPointMake(13.0f, 5.0f);
+  points[1] = CGPointMake(4.0f, 14.0f);
+  points[2] = CGPointMake(13.0f, 9.0f);
+  points[3] = CGPointMake(8.0f, 14.0f);
+  points[4] = CGPointMake(13.0f, 13.0f);
+  points[5] = CGPointMake(12.0f, 14.0f);
+  CGContextSetRGBStrokeColor(ctx, 0.13f, 0.13f, 0.13f, 0.54f);
+  CGContextStrokeLineSegments(ctx, points, 6);
+
+  points[0] = CGPointMake(13.0f, 6.0f);
+  points[1] = CGPointMake(5.0f, 14.0f);
+  points[2] = CGPointMake(13.0f, 10.0f);
+  points[3] = CGPointMake(9.0f, 14.0f);
+  points[5] = CGPointMake(13.0f, 13.9f);
+  points[4] = CGPointMake(13.0f, 14.0f);
+  CGContextSetRGBStrokeColor(ctx, 0.84f, 0.84f, 0.84f, 0.55f);
+  CGContextStrokeLineSegments(ctx, points, 6);
+
+  GLuint tex = 0;
+
+  ShaderProgramType shader = 
+#ifdef MOZ_ENABLE_LIBXUL
+    manager->gl()->UploadSurfaceToTexture(image, nsIntRect(0, 0, 15, 15), tex);
+#else
+    manager->gl()->UploadSurfaceToTextureExternal(image, nsIntRect(0, 0, 15, 15), tex);
+#endif
+
+  ColorTextureLayerProgram *program =
+    manager->GetColorTextureLayerProgram(shader);
+  program->Activate();
+  program->SetLayerQuadRect(nsIntRect(bottomX - 15,
+                                      bottomY - 15,
+                                      15,
+                                      15));
+  program->SetLayerTransform(gfx3DMatrix());
+  program->SetLayerOpacity(1.0);
+  program->SetRenderOffset(nsIntPoint(0,0));
+  program->SetTextureUnit(0);
+
+  manager->BindAndDrawQuad(program);
+  manager->gl()->fDeleteTextures(1, &tex);
+}
+
 nsTransparencyMode nsCocoaWindow::GetTransparencyMode()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
   return [mWindow isOpaque] ? eTransparencyOpaque : eTransparencyTransparent;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(eTransparencyOpaque);
 }
--- a/widget/src/xpwidgets/nsBaseWidget.h
+++ b/widget/src/xpwidgets/nsBaseWidget.h
@@ -113,16 +113,17 @@ public:
   virtual void            SetShowsToolbarButton(PRBool aShow) {}
   NS_IMETHOD              HideWindowChrome(PRBool aShouldHide);
   NS_IMETHOD              MakeFullScreen(PRBool aFullScreen);
   virtual nsIDeviceContext* GetDeviceContext();
   virtual nsIToolkit*     GetToolkit();
   virtual LayerManager*   GetLayerManager(bool *aAllowRetaining = nsnull);
   virtual LayerManager*   GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull);
+  virtual void            DrawOver(LayerManager* aManager, nsIntRect aRect) {}
   virtual gfxASurface*    GetThebesSurface();
   NS_IMETHOD              SetModal(PRBool aModal); 
   NS_IMETHOD              SetWindowClass(const nsAString& xulWinType);
   NS_IMETHOD              SetBounds(const nsIntRect &aRect);
   NS_IMETHOD              GetBounds(nsIntRect &aRect);
   NS_IMETHOD              GetClientBounds(nsIntRect &aRect);
   NS_IMETHOD              GetScreenBounds(nsIntRect &aRect);
   virtual nsIntPoint      GetClientOffset();