/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * 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"nsShmImage.h"
#ifdef MOZ_HAVE_SHMIMAGE # include "mozilla/X11Util.h" # include "mozilla/gfx/gfxVars.h" # include "mozilla/ipc/SharedMemory.h" # include "gfxPlatform.h" # include "nsPrintfCString.h" # include "nsTArray.h"
# include <dlfcn.h> # include <errno.h> # include <string.h> # include <sys/ipc.h> # include <sys/shm.h>
// If XShm isn't available to our client, we'll try XShm once, fail, // set this to false and then never try again. staticbool gShmAvailable = true; bool nsShmImage::UseShm() { return gShmAvailable; }
bool nsShmImage::InitExtension() { if (gShmInitialized) { return gShmAvailable;
}
gShmInitialized = true;
// Bugs 1397918, 1293474 - race condition in libxcb fixed upstream as of // version 1.11. Since we can't query libxcb's version directly, the only // other option is to check for symbols that were added after 1.11. // xcb_discard_reply64 was added in 1.11.1, so check for existence of // that to verify we are using a version of libxcb with the bug fixed. // Otherwise, we can't risk using libxcb due to aforementioned crashes. if (!dlsym(RTLD_DEFAULT, "xcb_discard_reply64")) {
gShmAvailable = false; returnfalse;
}
mFormat = SurfaceFormat::UNKNOWN; switch (mDepth) { case 32: if (mVisual->red_mask == 0xff0000 && mVisual->green_mask == 0xff00 &&
mVisual->blue_mask == 0xff) {
mFormat = SurfaceFormat::B8G8R8A8;
} break; case 24: // Only support the BGRX layout, and report it as BGRA to the compositor. // The alpha channel will be discarded when we put the image. // Cairo/pixman lacks some fast paths for compositing BGRX onto BGRA, so // just report it as BGRX directly in that case. if (mVisual->red_mask == 0xff0000 && mVisual->green_mask == 0xff00 &&
mVisual->blue_mask == 0xff) {
mFormat = backend == BackendType::CAIRO ? SurfaceFormat::B8G8R8X8
: SurfaceFormat::B8G8R8A8;
} break; case 16: if (mVisual->red_mask == 0xf800 && mVisual->green_mask == 0x07e0 &&
mVisual->blue_mask == 0x1f) {
mFormat = SurfaceFormat::R5G6B5_UINT16;
} break;
}
// Round up stride to the display's scanline pad (in bits) as XShm expects. int scanlinePad = _XGetScanlinePad(mDisplay, mDepth); int bitsPerPixel = _XGetBitsPerPixel(mDisplay, mDepth); int bitsPerLine =
((bitsPerPixel * aSize.width + scanlinePad - 1) / scanlinePad) *
scanlinePad;
mStride = bitsPerLine / 8;
if (!CreateShmSegment()) {
DestroyImage(); returnfalse;
}
void nsShmImage::DestroyImage() { if (mGC) {
xcb_free_gc(mConnection, mGC);
mGC = XCB_NONE;
} if (mPixmap != XCB_NONE) {
xcb_free_pixmap(mConnection, mPixmap);
mPixmap = XCB_NONE;
} if (mShmSeg != XCB_NONE) {
xcb_shm_detach_checked(mConnection, mShmSeg);
mShmSeg = XCB_NONE;
}
DestroyShmSegment(); // Avoid leaking any pending reply. No real need to wait but CentOS 6 build // machines don't have xcb_discard_reply().
WaitIfPendingReply();
}
// Wait for any in-flight shm-affected requests to complete. // Typically X clients would wait for a XShmCompletionEvent to be received, // but this works as it's sent immediately after the request is sent. void nsShmImage::WaitIfPendingReply() { if (mRequestPending) {
xcb_get_input_focus_reply_t* reply =
xcb_get_input_focus_reply(mConnection, mSyncRequest, nullptr);
free(reply);
mRequestPending = false;
}
}
// Due to bug 1205045, we must avoid making GTK calls off the main thread to // query window size. Instead we just track the largest offset within the // image we are drawing to and grow the image to accomodate it. Since usually // the entire window is invalidated on the first paint to it, this should grow // the image to the necessary size quickly without many intermediate // reallocations.
IntRect bounds = aRegion.GetBounds().ToUnknownRect();
IntSize size(bounds.XMost(), bounds.YMost()); if (size.width > mSize.width || size.height > mSize.height) {
DestroyImage(); if (!CreateImage(size)) { return nullptr;
}
}
// Send a request that returns a response so that we don't have to start a // sync in nsShmImage::CreateDrawTarget.
mSyncRequest = xcb_get_input_focus(mConnection);
mRequestPending = true;
xcb_flush(mConnection);
}
#endif// MOZ_HAVE_SHMIMAGE
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.