LCOV - code coverage report
Current view: directory - widget/shared - nsShmImage.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 59 0 0.0 %
Date: 2012-06-02 Functions: 5 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is the Mozilla browser.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Netscape Communications Corporation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 1999
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Chris Jones <jones.chris.g@gmail.com>
      25                 :  *   Oleg Romashin <romaxa@gmail.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_GTK3)
      42                 : #include <gtk/gtk.h>
      43                 : #include <gdk/gdkx.h>
      44                 : #elif defined(MOZ_WIDGET_QT)
      45                 : #include <QWidget>
      46                 : #endif
      47                 : 
      48                 : #include "nsShmImage.h"
      49                 : #include "gfxPlatform.h"
      50                 : #include "gfxImageSurface.h"
      51                 : 
      52                 : #ifdef MOZ_HAVE_SHMIMAGE
      53                 : 
      54                 : using namespace mozilla::ipc;
      55                 : 
      56                 : // If XShm isn't available to our client, we'll try XShm once, fail,
      57                 : // set this to false and then never try again.
      58                 : static bool gShmAvailable = true;
      59               0 : bool nsShmImage::UseShm()
      60                 : {
      61                 :     return gfxPlatform::GetPlatform()->
      62               0 :         ScreenReferenceSurface()->GetType() == gfxASurface::SurfaceTypeImage
      63               0 :         && gShmAvailable;
      64                 : }
      65                 : 
      66                 : already_AddRefed<nsShmImage>
      67               0 : nsShmImage::Create(const gfxIntSize& aSize,
      68                 :                    Visual* aVisual, unsigned int aDepth)
      69                 : {
      70               0 :     Display* dpy = DISPLAY();
      71                 : 
      72               0 :     nsRefPtr<nsShmImage> shm = new nsShmImage();
      73               0 :     shm->mImage = XShmCreateImage(dpy, aVisual, aDepth,
      74                 :                                   ZPixmap, nsnull,
      75               0 :                                   &(shm->mInfo),
      76               0 :                                   aSize.width, aSize.height);
      77               0 :     if (!shm->mImage) {
      78               0 :         return nsnull;
      79                 :     }
      80                 : 
      81                 :     size_t size = SharedMemory::PageAlignedSize(
      82               0 :         shm->mImage->bytes_per_line * shm->mImage->height);
      83               0 :     shm->mSegment = new SharedMemorySysV();
      84               0 :     if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) {
      85               0 :         return nsnull;
      86                 :     }
      87                 : 
      88               0 :     shm->mInfo.shmid = shm->mSegment->GetHandle();
      89               0 :     shm->mInfo.shmaddr =
      90               0 :         shm->mImage->data = static_cast<char*>(shm->mSegment->memory());
      91               0 :     shm->mInfo.readOnly = False;
      92                 : 
      93               0 :     int xerror = 0;
      94                 : #if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_GTK3)
      95               0 :     gdk_error_trap_push();
      96               0 :     Status attachOk = XShmAttach(dpy, &shm->mInfo);
      97               0 :     XSync(dpy, False);
      98               0 :     xerror = gdk_error_trap_pop();
      99                 : #elif defined(MOZ_WIDGET_QT)
     100                 :     Status attachOk = XShmAttach(dpy, &shm->mInfo);
     101                 : #endif
     102                 : 
     103               0 :     if (!attachOk || xerror) {
     104                 :         // Assume XShm isn't available, and don't attempt to use it
     105                 :         // again.
     106               0 :         gShmAvailable = false;
     107               0 :         return nsnull;
     108                 :     }
     109                 : 
     110               0 :     shm->mXAttached = true;
     111               0 :     shm->mSize = aSize;
     112               0 :     switch (shm->mImage->depth) {
     113                 :     case 24:
     114                 :         // Only xRGB is supported.
     115               0 :         if ((shm->mImage->red_mask == 0xff0000) &&
     116               0 :             (shm->mImage->green_mask == 0xff00) &&
     117               0 :             (shm->mImage->blue_mask == 0xff)) {
     118               0 :             shm->mFormat = gfxASurface::ImageFormatRGB24;
     119               0 :             break;
     120                 :         }
     121               0 :         goto unsupported;
     122                 :     case 16:
     123               0 :         shm->mFormat = gfxASurface::ImageFormatRGB16_565; break;
     124                 :     unsupported:
     125                 :     default:
     126               0 :         NS_WARNING("Unsupported XShm Image format!");
     127               0 :         gShmAvailable = false;
     128               0 :         return nsnull;
     129                 :     }
     130               0 :     return shm.forget();
     131                 : }
     132                 : 
     133                 : already_AddRefed<gfxASurface>
     134               0 : nsShmImage::AsSurface()
     135                 : {
     136                 :     return nsRefPtr<gfxASurface>(
     137               0 :         new gfxImageSurface(static_cast<unsigned char*>(mSegment->memory()),
     138                 :                             mSize,
     139                 :                             mImage->bytes_per_line,
     140               0 :                             mFormat)
     141               0 :         ).forget();
     142                 : }
     143                 : 
     144                 : #if defined(MOZ_WIDGET_GTK2)
     145                 : void
     146               0 : nsShmImage::Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd)
     147                 : {
     148                 :     GdkDrawable* gd;
     149                 :     gint dx, dy;
     150               0 :     gdk_window_get_internal_paint_info(aWindow, &gd, &dx, &dy);
     151                 : 
     152               0 :     Display* dpy = gdk_x11_get_default_xdisplay();
     153               0 :     Drawable d = GDK_DRAWABLE_XID(gd);
     154                 : 
     155               0 :     GC gc = XCreateGC(dpy, d, 0, nsnull);
     156               0 :     for (GdkRectangle* r = aRects; r < aEnd; r++) {
     157                 :         XShmPutImage(dpy, d, gc, mImage,
     158                 :                      r->x, r->y,
     159                 :                      r->x - dx, r->y - dy,
     160                 :                      r->width, r->height,
     161               0 :                      False);
     162                 :     }
     163               0 :     XFreeGC(dpy, gc);
     164                 : 
     165                 :     // FIXME/bug 597336: we need to ensure that the shm image isn't
     166                 :     // scribbled over before all its pending XShmPutImage()s complete.
     167                 :     // However, XSync() is an unnecessarily heavyweight
     168                 :     // synchronization mechanism; other options are possible.  If this
     169                 :     // XSync is shown to hurt responsiveness, we need to explore the
     170                 :     // other options.
     171               0 :     XSync(dpy, False);
     172               0 : }
     173                 : 
     174                 : #elif defined(MOZ_WIDGET_GTK3)
     175                 : void
     176                 : nsShmImage::Put(GdkWindow* aWindow, cairo_rectangle_list_t* aRects)
     177                 : {
     178                 :     Display* dpy = gdk_x11_get_default_xdisplay();
     179                 :     Drawable d = GDK_WINDOW_XID(aWindow);
     180                 :     int dx = 0, dy = 0;
     181                 : 
     182                 :     GC gc = XCreateGC(dpy, d, 0, nsnull);
     183                 :     cairo_rectangle_t r;
     184                 :     for (int i = 0; i < aRects->num_rectangles; i++) {
     185                 :         r = aRects->rectangles[i];
     186                 :         XShmPutImage(dpy, d, gc, mImage,
     187                 :                      r.x, r.y,
     188                 :                      r.x - dx, r.y - dy,
     189                 :                      r.width, r.height,
     190                 :                      False);
     191                 :     }
     192                 : 
     193                 :     XFreeGC(dpy, gc);
     194                 : 
     195                 :     // FIXME/bug 597336: we need to ensure that the shm image isn't
     196                 :     // scribbled over before all its pending XShmPutImage()s complete.
     197                 :     // However, XSync() is an unnecessarily heavyweight
     198                 :     // synchronization mechanism; other options are possible.  If this
     199                 :     // XSync is shown to hurt responsiveness, we need to explore the
     200                 :     // other options.
     201                 :     XSync(dpy, False);
     202                 : }
     203                 : 
     204                 : #elif defined(MOZ_WIDGET_QT)
     205                 : void
     206                 : nsShmImage::Put(QWidget* aWindow, QRect& aRect)
     207                 : {
     208                 :     Display* dpy = aWindow->x11Info().display();
     209                 :     Drawable d = aWindow->handle();
     210                 : 
     211                 :     GC gc = XCreateGC(dpy, d, 0, nsnull);
     212                 :     // Avoid out of bounds painting
     213                 :     QRect inter = aRect.intersected(aWindow->rect());
     214                 :     XShmPutImage(dpy, d, gc, mImage,
     215                 :                  inter.x(), inter.y(),
     216                 :                  inter.x(), inter.y(),
     217                 :                  inter.width(), inter.height(),
     218                 :                  False);
     219                 :     XFreeGC(dpy, gc);
     220                 : }
     221                 : #endif
     222                 : 
     223                 : already_AddRefed<gfxASurface>
     224               0 : nsShmImage::EnsureShmImage(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth,
     225                 :                nsRefPtr<nsShmImage>& aImage)
     226                 : {
     227               0 :     if (!aImage || aImage->Size() != aSize) {
     228                 :         // Because we XSync() after XShmAttach() to trap errors, we
     229                 :         // know that the X server has the old image's memory mapped
     230                 :         // into its address space, so it's OK to destroy the old image
     231                 :         // here even if there are outstanding Puts.  The Detach is
     232                 :         // ordered after the Puts.
     233               0 :         aImage = nsShmImage::Create(aSize, aVisual, aDepth);
     234                 :     }
     235               0 :     return !aImage ? nsnull : aImage->AsSurface();
     236                 : }
     237                 : 
     238                 : #endif  // defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)

Generated by: LCOV version 1.7