LCOV - code coverage report
Current view: top level - gfx/thebes - gfxXlibSurface.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 253 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 35 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "gfxXlibSurface.h"
       7             : 
       8             : #include "cairo.h"
       9             : #include "cairo-xlib.h"
      10             : #include "cairo-xlib-xrender.h"
      11             : #include <X11/Xlibint.h>  /* For XESetCloseDisplay */
      12             : #undef max // Xlibint.h defines this and it breaks std::max
      13             : #undef min // Xlibint.h defines this and it breaks std::min
      14             : 
      15             : #include "nsTArray.h"
      16             : #include "nsAlgorithm.h"
      17             : #include "mozilla/gfx/2D.h"
      18             : #include "mozilla/Preferences.h"
      19             : #include <algorithm>
      20             : #include "mozilla/CheckedInt.h"
      21             : 
      22             : using namespace mozilla;
      23             : using namespace mozilla::gfx;
      24             : 
      25           0 : gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual)
      26             :     : mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
      27             : #if defined(GL_PROVIDER_GLX)
      28           0 :     , mGLXPixmap(X11None)
      29             : #endif
      30             : {
      31           0 :     const gfx::IntSize size = DoSizeQuery();
      32           0 :     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, size.width, size.height);
      33           0 :     Init(surf);
      34           0 : }
      35             : 
      36           0 : gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfx::IntSize& size)
      37             :     : mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable)
      38             : #if defined(GL_PROVIDER_GLX)
      39           0 :     , mGLXPixmap(X11None)
      40             : #endif
      41             : {
      42           0 :     NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
      43             :                  "Bad size");
      44             : 
      45           0 :     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, size.width, size.height);
      46           0 :     Init(surf);
      47           0 : }
      48             : 
      49           0 : gfxXlibSurface::gfxXlibSurface(Screen *screen, Drawable drawable, XRenderPictFormat *format,
      50           0 :                                const gfx::IntSize& size)
      51           0 :     : mPixmapTaken(false), mDisplay(DisplayOfScreen(screen)),
      52             :       mDrawable(drawable)
      53             : #if defined(GL_PROVIDER_GLX)
      54           0 :       , mGLXPixmap(X11None)
      55             : #endif
      56             : {
      57           0 :     NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
      58             :                  "Bad Size");
      59             : 
      60             :     cairo_surface_t *surf =
      61           0 :         cairo_xlib_surface_create_with_xrender_format(mDisplay, drawable,
      62             :                                                       screen, format,
      63           0 :                                                       size.width, size.height);
      64           0 :     Init(surf);
      65           0 : }
      66             : 
      67           0 : gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
      68             :     : mPixmapTaken(false)
      69             : #if defined(GL_PROVIDER_GLX)
      70           0 :       , mGLXPixmap(X11None)
      71             : #endif
      72             : {
      73           0 :     NS_PRECONDITION(cairo_surface_status(csurf) == 0,
      74             :                     "Not expecting an error surface");
      75             : 
      76           0 :     mDrawable = cairo_xlib_surface_get_drawable(csurf);
      77           0 :     mDisplay = cairo_xlib_surface_get_display(csurf);
      78             : 
      79           0 :     Init(csurf, true);
      80           0 : }
      81             : 
      82           0 : gfxXlibSurface::~gfxXlibSurface()
      83             : {
      84             :     // gfxASurface's destructor calls RecordMemoryFreed().
      85           0 :     if (mPixmapTaken) {
      86             : #if defined(GL_PROVIDER_GLX)
      87           0 :         if (mGLXPixmap) {
      88           0 :             gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
      89             :         }
      90             : #endif
      91           0 :         XFreePixmap (mDisplay, mDrawable);
      92             :     }
      93           0 : }
      94             : 
      95             : static Drawable
      96           0 : CreatePixmap(Screen *screen, const gfx::IntSize& size, unsigned int depth,
      97             :              Drawable relatedDrawable)
      98             : {
      99           0 :     if (!Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
     100           0 :         return X11None;
     101             : 
     102           0 :     if (relatedDrawable == X11None) {
     103           0 :         relatedDrawable = RootWindowOfScreen(screen);
     104             :     }
     105           0 :     Display *dpy = DisplayOfScreen(screen);
     106             :     // X gives us a fatal error if we try to create a pixmap of width
     107             :     // or height 0
     108           0 :     return XCreatePixmap(dpy, relatedDrawable,
     109           0 :                          std::max(1, size.width), std::max(1, size.height),
     110           0 :                          depth);
     111             : }
     112             : 
     113             : void
     114           0 : gfxXlibSurface::TakePixmap()
     115             : {
     116           0 :     NS_ASSERTION(!mPixmapTaken, "I already own the Pixmap!");
     117           0 :     mPixmapTaken = true;
     118             : 
     119             :     // The bit depth returned from Cairo is technically int, but this is
     120             :     // the last place we'd be worried about that scenario.
     121           0 :     unsigned int bitDepth = cairo_xlib_surface_get_depth(CairoSurface());
     122           0 :     MOZ_ASSERT((bitDepth % 8) == 0, "Memory used not recorded correctly");    
     123             : 
     124             :     // Divide by 8 because surface_get_depth gives us the number of *bits* per
     125             :     // pixel.
     126           0 :     gfx::IntSize size = GetSize();
     127           0 :     CheckedInt32 totalBytes = CheckedInt32(size.width) * CheckedInt32(size.height) * (bitDepth/8);
     128             : 
     129             :     // Don't do anything in the "else" case.  We could add INT32_MAX, but that
     130             :     // would overflow the memory used counter.  It would also mean we tried for
     131             :     // a 2G image.  For now, we'll just assert,
     132           0 :     MOZ_ASSERT(totalBytes.isValid(),"Did not expect to exceed 2Gb image");
     133           0 :     if (totalBytes.isValid()) {
     134           0 :         RecordMemoryUsed(totalBytes.value());
     135             :     }
     136           0 : }
     137             : 
     138             : Drawable
     139           0 : gfxXlibSurface::ReleasePixmap() {
     140           0 :     NS_ASSERTION(mPixmapTaken, "I don't own the Pixmap!");
     141           0 :     mPixmapTaken = false;
     142           0 :     RecordMemoryFreed();
     143           0 :     return mDrawable;
     144             : }
     145             : 
     146             : static cairo_user_data_key_t gDestroyPixmapKey;
     147             : 
     148             : struct DestroyPixmapClosure {
     149           0 :     DestroyPixmapClosure(Drawable d, Screen *s) : mPixmap(d), mScreen(s) {}
     150             :     Drawable mPixmap;
     151             :     Screen *mScreen;
     152             : };
     153             : 
     154             : static void
     155           0 : DestroyPixmap(void *data)
     156             : {
     157           0 :     DestroyPixmapClosure *closure = static_cast<DestroyPixmapClosure*>(data);
     158           0 :     XFreePixmap(DisplayOfScreen(closure->mScreen), closure->mPixmap);
     159             :     delete closure;
     160           0 : }
     161             : 
     162             : /* static */
     163             : cairo_surface_t *
     164           0 : gfxXlibSurface::CreateCairoSurface(Screen *screen, Visual *visual,
     165             :                                    const gfx::IntSize& size, Drawable relatedDrawable)
     166             : {
     167             :     Drawable drawable =
     168           0 :         CreatePixmap(screen, size, DepthOfVisual(screen, visual),
     169           0 :                      relatedDrawable);
     170           0 :     if (!drawable)
     171           0 :         return nullptr;
     172             : 
     173             :     cairo_surface_t* surface =
     174           0 :         cairo_xlib_surface_create(DisplayOfScreen(screen), drawable, visual,
     175           0 :                                   size.width, size.height);
     176           0 :     if (cairo_surface_status(surface)) {
     177           0 :         cairo_surface_destroy(surface);
     178           0 :         XFreePixmap(DisplayOfScreen(screen), drawable);
     179           0 :         return nullptr;
     180             :     }
     181             : 
     182           0 :     DestroyPixmapClosure *closure = new DestroyPixmapClosure(drawable, screen);
     183             :     cairo_surface_set_user_data(surface, &gDestroyPixmapKey,
     184           0 :                                 closure, DestroyPixmap);
     185           0 :     return surface;
     186             : }
     187             : 
     188             : /* static */
     189             : already_AddRefed<gfxXlibSurface>
     190           0 : gfxXlibSurface::Create(Screen *screen, Visual *visual,
     191             :                        const gfx::IntSize& size, Drawable relatedDrawable)
     192             : {
     193             :     Drawable drawable =
     194           0 :         CreatePixmap(screen, size, DepthOfVisual(screen, visual),
     195           0 :                      relatedDrawable);
     196           0 :     if (!drawable)
     197           0 :         return nullptr;
     198             : 
     199             :     RefPtr<gfxXlibSurface> result =
     200           0 :         new gfxXlibSurface(DisplayOfScreen(screen), drawable, visual, size);
     201           0 :     result->TakePixmap();
     202             : 
     203           0 :     if (result->CairoStatus() != 0)
     204           0 :         return nullptr;
     205             : 
     206           0 :     return result.forget();
     207             : }
     208             : 
     209             : /* static */
     210             : already_AddRefed<gfxXlibSurface>
     211           0 : gfxXlibSurface::Create(Screen *screen, XRenderPictFormat *format,
     212             :                        const gfx::IntSize& size, Drawable relatedDrawable)
     213             : {
     214             :     Drawable drawable =
     215           0 :         CreatePixmap(screen, size, format->depth, relatedDrawable);
     216           0 :     if (!drawable)
     217           0 :         return nullptr;
     218             : 
     219             :     RefPtr<gfxXlibSurface> result =
     220           0 :         new gfxXlibSurface(screen, drawable, format, size);
     221           0 :     result->TakePixmap();
     222             : 
     223           0 :     if (result->CairoStatus() != 0)
     224           0 :         return nullptr;
     225             : 
     226           0 :     return result.forget();
     227             : }
     228             : 
     229           0 : static bool GetForce24bppPref()
     230             : {
     231           0 :     return Preferences::GetBool("mozilla.widget.force-24bpp", false);
     232             : }
     233             : 
     234             : already_AddRefed<gfxASurface>
     235           0 : gfxXlibSurface::CreateSimilarSurface(gfxContentType aContent,
     236             :                                      const gfx::IntSize& aSize)
     237             : {
     238           0 :     if (!mSurface || !mSurfaceValid) {
     239           0 :       return nullptr;
     240             :     }
     241             : 
     242           0 :     if (aContent == gfxContentType::COLOR) {
     243             :         // cairo_surface_create_similar will use a matching visual if it can.
     244             :         // However, systems with 16-bit or indexed default visuals may benefit
     245             :         // from rendering with 24-bit formats.
     246           0 :         static bool force24bpp = GetForce24bppPref();
     247           0 :         if (force24bpp
     248           0 :             && cairo_xlib_surface_get_depth(CairoSurface()) != 24) {
     249             :             XRenderPictFormat* format =
     250           0 :                 XRenderFindStandardFormat(mDisplay, PictStandardRGB24);
     251           0 :             if (format) {
     252             :                 // Cairo only performs simple self-copies as desired if it
     253             :                 // knows that this is a Pixmap surface.  It only knows that
     254             :                 // surfaces are pixmap surfaces if it creates the Pixmap
     255             :                 // itself, so we use cairo_surface_create_similar with a
     256             :                 // temporary reference surface to indicate the format.
     257           0 :                 Screen* screen = cairo_xlib_surface_get_screen(CairoSurface());
     258             :                 RefPtr<gfxXlibSurface> depth24reference =
     259           0 :                     gfxXlibSurface::Create(screen, format,
     260           0 :                                            gfx::IntSize(1, 1), mDrawable);
     261           0 :                 if (depth24reference)
     262           0 :                     return depth24reference->
     263           0 :                         gfxASurface::CreateSimilarSurface(aContent, aSize);
     264             :             }
     265             :         }
     266             :     }
     267             : 
     268           0 :     return gfxASurface::CreateSimilarSurface(aContent, aSize);
     269             : }
     270             : 
     271             : void
     272           0 : gfxXlibSurface::Finish()
     273             : {
     274             : #if defined(GL_PROVIDER_GLX)
     275           0 :     if (mPixmapTaken && mGLXPixmap) {
     276           0 :         gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
     277           0 :         mGLXPixmap = X11None;
     278             :     }
     279             : #endif
     280           0 :     gfxASurface::Finish();
     281           0 : }
     282             : 
     283             : const gfx::IntSize
     284           0 : gfxXlibSurface::GetSize() const
     285             : {
     286           0 :     if (!mSurfaceValid)
     287           0 :         return gfx::IntSize(0,0);
     288             : 
     289           0 :     return gfx::IntSize(cairo_xlib_surface_get_width(mSurface),
     290           0 :                       cairo_xlib_surface_get_height(mSurface));
     291             : }
     292             : 
     293             : const gfx::IntSize
     294           0 : gfxXlibSurface::DoSizeQuery()
     295             : {
     296             :     // figure out width/height/depth
     297             :     Window root_ignore;
     298             :     int x_ignore, y_ignore;
     299             :     unsigned int bwidth_ignore, width, height, depth;
     300             : 
     301           0 :     XGetGeometry(mDisplay,
     302             :                  mDrawable,
     303             :                  &root_ignore, &x_ignore, &y_ignore,
     304             :                  &width, &height,
     305           0 :                  &bwidth_ignore, &depth);
     306             : 
     307           0 :     return gfx::IntSize(width, height);
     308             : }
     309             : 
     310           0 : class DisplayTable {
     311             : public:
     312             :     static bool GetColormapAndVisual(Screen* screen,
     313             :                                        XRenderPictFormat* format,
     314             :                                        Visual* visual, Colormap* colormap,
     315             :                                        Visual** visualForColormap);
     316             : 
     317             : private:
     318             :     struct ColormapEntry {
     319             :         XRenderPictFormat* mFormat;
     320             :         // The Screen is needed here because colormaps (and their visuals) may
     321             :         // only be used on one Screen, but XRenderPictFormats are not unique
     322             :         // to any one Screen.
     323             :         Screen* mScreen;
     324             :         Visual* mVisual;
     325             :         Colormap mColormap;
     326             :     };
     327             : 
     328           0 :     class DisplayInfo {
     329             :     public:
     330           0 :         explicit DisplayInfo(Display* display) : mDisplay(display) { }
     331             :         Display* mDisplay;
     332             :         nsTArray<ColormapEntry> mColormapEntries;
     333             :     };
     334             : 
     335             :     // Comparator for finding the DisplayInfo
     336             :     class FindDisplay {
     337             :     public:
     338           0 :         bool Equals(const DisplayInfo& info, const Display *display) const
     339             :         {
     340           0 :             return info.mDisplay == display;
     341             :         }
     342             :     };
     343             : 
     344             :     static int DisplayClosing(Display *display, XExtCodes* codes);
     345             : 
     346             :     nsTArray<DisplayInfo> mDisplays;
     347             :     static DisplayTable* sDisplayTable;
     348             : };
     349             : 
     350             : DisplayTable* DisplayTable::sDisplayTable;
     351             : 
     352             : // Pixmaps don't have a particular associated visual but the pixel values are
     353             : // interpreted according to a visual/colormap pairs.
     354             : //
     355             : // cairo is designed for surfaces with either TrueColor visuals or the
     356             : // default visual (which may not be true color).  TrueColor visuals don't
     357             : // really need a colormap because the visual indicates the pixel format,
     358             : // and cairo uses the default visual with the default colormap, so cairo
     359             : // surfaces don't need an explicit colormap.
     360             : //
     361             : // However, some toolkits (e.g. GDK) need a colormap even with TrueColor
     362             : // visuals.  We can create a colormap for these visuals, but it will use about
     363             : // 20kB of memory in the server, so we use the default colormap when
     364             : // suitable and share colormaps between surfaces.  Another reason for
     365             : // minimizing colormap turnover is that the plugin process must leak resources
     366             : // for each new colormap id when using older GDK libraries (bug 569775).
     367             : //
     368             : // Only the format of the pixels is important for rendering to Pixmaps, so if
     369             : // the format of a visual matches that of the surface, then that visual can be
     370             : // used for rendering to the surface.  Multiple visuals can match the same
     371             : // format (but have different GLX properties), so the visual returned may
     372             : // differ from the visual passed in.  Colormaps are tied to a visual, so
     373             : // should only be used with their visual.
     374             : 
     375             : /* static */ bool
     376           0 : DisplayTable::GetColormapAndVisual(Screen* aScreen, XRenderPictFormat* aFormat,
     377             :                                    Visual* aVisual, Colormap* aColormap,
     378             :                                    Visual** aVisualForColormap)
     379             : 
     380             : {
     381           0 :     Display* display = DisplayOfScreen(aScreen);
     382             : 
     383             :     // Use the default colormap if the default visual matches.
     384           0 :     Visual *defaultVisual = DefaultVisualOfScreen(aScreen);
     385           0 :     if (aVisual == defaultVisual
     386           0 :         || (aFormat
     387           0 :             && aFormat == XRenderFindVisualFormat(display, defaultVisual)))
     388             :     {
     389           0 :         *aColormap = DefaultColormapOfScreen(aScreen);
     390           0 :         *aVisualForColormap = defaultVisual;
     391           0 :         return true;
     392             :     }
     393             : 
     394             :     // Only supporting TrueColor non-default visuals
     395           0 :     if (!aVisual || aVisual->c_class != TrueColor)
     396           0 :         return false;
     397             : 
     398           0 :     if (!sDisplayTable) {
     399           0 :         sDisplayTable = new DisplayTable();
     400             :     }
     401             : 
     402           0 :     nsTArray<DisplayInfo>* displays = &sDisplayTable->mDisplays;
     403           0 :     size_t d = displays->IndexOf(display, 0, FindDisplay());
     404             : 
     405           0 :     if (d == displays->NoIndex) {
     406           0 :         d = displays->Length();
     407             :         // Register for notification of display closing, when this info
     408             :         // becomes invalid.
     409           0 :         XExtCodes *codes = XAddExtension(display);
     410           0 :         if (!codes)
     411           0 :             return false;
     412             : 
     413           0 :         XESetCloseDisplay(display, codes->extension, DisplayClosing);
     414             :         // Add a new DisplayInfo.
     415           0 :         displays->AppendElement(display);
     416             :     }
     417             : 
     418             :     nsTArray<ColormapEntry>* entries =
     419           0 :         &displays->ElementAt(d).mColormapEntries;
     420             : 
     421             :     // Only a small number of formats are expected to be used, so just do a
     422             :     // simple linear search.
     423           0 :     for (uint32_t i = 0; i < entries->Length(); ++i) {
     424           0 :         const ColormapEntry& entry = entries->ElementAt(i);
     425             :         // Only the format and screen need to match.  (The visual may differ.)
     426             :         // If there is no format (e.g. no RENDER extension) then just compare
     427             :         // the visual.
     428           0 :         if ((aFormat && entry.mFormat == aFormat && entry.mScreen == aScreen)
     429           0 :             || aVisual == entry.mVisual) {
     430           0 :             *aColormap = entry.mColormap;
     431           0 :             *aVisualForColormap = entry.mVisual;
     432           0 :             return true;
     433             :         }
     434             :     }
     435             : 
     436             :     // No existing entry.  Create a colormap and add an entry.
     437           0 :     Colormap colormap = XCreateColormap(display, RootWindowOfScreen(aScreen),
     438           0 :                                         aVisual, AllocNone);
     439           0 :     ColormapEntry* newEntry = entries->AppendElement();
     440           0 :     newEntry->mFormat = aFormat;
     441           0 :     newEntry->mScreen = aScreen;
     442           0 :     newEntry->mVisual = aVisual;
     443           0 :     newEntry->mColormap = colormap;
     444             : 
     445           0 :     *aColormap = colormap;
     446           0 :     *aVisualForColormap = aVisual;
     447           0 :     return true;
     448             : }
     449             : 
     450             : /* static */ int
     451           0 : DisplayTable::DisplayClosing(Display *display, XExtCodes* codes)
     452             : {
     453             :     // No need to free the colormaps explicitly as they will be released when
     454             :     // the connection is closed.
     455           0 :     sDisplayTable->mDisplays.RemoveElement(display, FindDisplay());
     456           0 :     if (sDisplayTable->mDisplays.Length() == 0) {
     457           0 :         delete sDisplayTable;
     458           0 :         sDisplayTable = nullptr;
     459             :     }
     460           0 :     return 0;
     461             : }
     462             : 
     463             : /* static */
     464             : bool
     465           0 : gfxXlibSurface::GetColormapAndVisual(cairo_surface_t* aXlibSurface,
     466             :                                      Colormap* aColormap, Visual** aVisual)
     467             : {
     468             :     XRenderPictFormat* format =
     469           0 :         cairo_xlib_surface_get_xrender_format(aXlibSurface);
     470           0 :     Screen* screen = cairo_xlib_surface_get_screen(aXlibSurface);
     471           0 :     Visual* visual = cairo_xlib_surface_get_visual(aXlibSurface);
     472             : 
     473             :     return DisplayTable::GetColormapAndVisual(screen, format, visual,
     474           0 :                                               aColormap, aVisual);
     475             : }
     476             : 
     477             : bool
     478           0 : gfxXlibSurface::GetColormapAndVisual(Colormap* aColormap, Visual** aVisual)
     479             : {
     480           0 :     if (!mSurfaceValid)
     481           0 :         return false;
     482             : 
     483           0 :     return GetColormapAndVisual(CairoSurface(), aColormap, aVisual);
     484             : }
     485             : 
     486             : /* static */
     487             : int
     488           0 : gfxXlibSurface::DepthOfVisual(const Screen* screen, const Visual* visual)
     489             : {
     490           0 :     for (int d = 0; d < screen->ndepths; d++) {
     491           0 :         const Depth& d_info = screen->depths[d];
     492           0 :         if (visual >= &d_info.visuals[0]
     493           0 :             && visual < &d_info.visuals[d_info.nvisuals])
     494           0 :             return d_info.depth;
     495             :     }
     496             : 
     497           0 :     NS_ERROR("Visual not on Screen.");
     498           0 :     return 0;
     499             : }
     500             :     
     501             : /* static */
     502             : Visual*
     503           0 : gfxXlibSurface::FindVisual(Screen *screen, gfxImageFormat format)
     504             : {
     505             :     int depth;
     506             :     unsigned long red_mask, green_mask, blue_mask;
     507           0 :     switch (format) {
     508             :         case gfx::SurfaceFormat::A8R8G8B8_UINT32:
     509           0 :             depth = 32;
     510           0 :             red_mask = 0xff0000;
     511           0 :             green_mask = 0xff00;
     512           0 :             blue_mask = 0xff;
     513           0 :             break;
     514             :         case gfx::SurfaceFormat::X8R8G8B8_UINT32:
     515           0 :             depth = 24;
     516           0 :             red_mask = 0xff0000;
     517           0 :             green_mask = 0xff00;
     518           0 :             blue_mask = 0xff;
     519           0 :             break;
     520             :         case gfx::SurfaceFormat::R5G6B5_UINT16:
     521           0 :             depth = 16;
     522           0 :             red_mask = 0xf800;
     523           0 :             green_mask = 0x7e0;
     524           0 :             blue_mask = 0x1f;
     525           0 :             break;
     526             :         case gfx::SurfaceFormat::A8:
     527             :         default:
     528           0 :             return nullptr;
     529             :     }
     530             : 
     531           0 :     for (int d = 0; d < screen->ndepths; d++) {
     532           0 :         const Depth& d_info = screen->depths[d];
     533           0 :         if (d_info.depth != depth)
     534           0 :             continue;
     535             : 
     536           0 :         for (int v = 0; v < d_info.nvisuals; v++) {
     537           0 :             Visual* visual = &d_info.visuals[v];
     538             : 
     539           0 :             if (visual->c_class == TrueColor &&
     540           0 :                 visual->red_mask == red_mask &&
     541           0 :                 visual->green_mask == green_mask &&
     542           0 :                 visual->blue_mask == blue_mask)
     543           0 :                 return visual;
     544             :         }
     545             :     }
     546             : 
     547           0 :     return nullptr;
     548             : }
     549             : 
     550             : /* static */
     551             : XRenderPictFormat*
     552           0 : gfxXlibSurface::FindRenderFormat(Display *dpy, gfxImageFormat format)
     553             : {
     554           0 :     switch (format) {
     555             :         case gfx::SurfaceFormat::A8R8G8B8_UINT32:
     556           0 :             return XRenderFindStandardFormat (dpy, PictStandardARGB32);
     557             :         case gfx::SurfaceFormat::X8R8G8B8_UINT32:
     558           0 :             return XRenderFindStandardFormat (dpy, PictStandardRGB24);
     559             :         case gfx::SurfaceFormat::R5G6B5_UINT16: {
     560             :             // PictStandardRGB16_565 is not standard Xrender format
     561             :             // we should try to find related visual
     562             :             // and find xrender format by visual
     563           0 :             Visual *visual = FindVisual(DefaultScreenOfDisplay(dpy), format);
     564           0 :             if (!visual)
     565           0 :                 return nullptr;
     566           0 :             return XRenderFindVisualFormat(dpy, visual);
     567             :         }
     568             :         case gfx::SurfaceFormat::A8:
     569           0 :             return XRenderFindStandardFormat (dpy, PictStandardA8);
     570             :         default:
     571           0 :             break;
     572             :     }
     573             : 
     574           0 :     return nullptr;
     575             : }
     576             : 
     577             : Screen*
     578           0 : gfxXlibSurface::XScreen()
     579             : {
     580           0 :     return cairo_xlib_surface_get_screen(CairoSurface());
     581             : }
     582             : 
     583             : XRenderPictFormat*
     584           0 : gfxXlibSurface::XRenderFormat()
     585             : {
     586           0 :     return cairo_xlib_surface_get_xrender_format(CairoSurface());
     587             : }
     588             : 
     589             : #if defined(GL_PROVIDER_GLX)
     590             : GLXPixmap
     591           0 : gfxXlibSurface::GetGLXPixmap()
     592             : {
     593           0 :     if (!mGLXPixmap) {
     594             : #ifdef DEBUG
     595             :         // cairo_surface_has_show_text_glyphs is used solely for the
     596             :         // side-effect of setting the error on surface if
     597             :         // cairo_surface_finish() has been called.
     598           0 :         cairo_surface_has_show_text_glyphs(CairoSurface());
     599           0 :         NS_ASSERTION(CairoStatus() != CAIRO_STATUS_SURFACE_FINISHED,
     600             :             "GetGLXPixmap called after surface finished");
     601             : #endif
     602           0 :         mGLXPixmap = gl::sGLXLibrary.CreatePixmap(this);
     603             :     }
     604           0 :     return mGLXPixmap;
     605             : }
     606             : 
     607             : void
     608           0 : gfxXlibSurface::BindGLXPixmap(GLXPixmap aPixmap)
     609             : {
     610           0 :     MOZ_ASSERT(!mGLXPixmap, "A GLXPixmap is already bound!");
     611           0 :     mGLXPixmap = aPixmap;
     612           0 : }
     613             : 
     614             : #endif

Generated by: LCOV version 1.13