Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "WindowSurfaceXRender.h"
8 :
9 : #include "mozilla/gfx/2D.h"
10 : #include "mozilla/gfx/Types.h"
11 : #include "gfxPlatform.h"
12 :
13 : namespace mozilla {
14 : namespace widget {
15 :
16 0 : WindowSurfaceXRender::WindowSurfaceXRender(Display* aDisplay,
17 : Window aWindow,
18 : Visual* aVisual,
19 0 : unsigned int aDepth)
20 : : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth)
21 : , mXlibSurface(nullptr)
22 0 : , mGC(X11None)
23 : {
24 0 : }
25 :
26 0 : WindowSurfaceXRender::~WindowSurfaceXRender()
27 : {
28 0 : if (mGC != X11None) {
29 0 : XFreeGC(mDisplay, mGC);
30 : }
31 0 : }
32 :
33 : already_AddRefed<gfx::DrawTarget>
34 0 : WindowSurfaceXRender::Lock(const LayoutDeviceIntRegion& aRegion)
35 : {
36 0 : gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
37 0 : gfx::IntSize size(bounds.XMost(), bounds.YMost());
38 0 : if (!mXlibSurface || mXlibSurface->CairoStatus() ||
39 0 : !(size <= mXlibSurface->GetSize())) {
40 0 : mXlibSurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(mDisplay),
41 0 : mVisual,
42 : size,
43 0 : mWindow);
44 : }
45 0 : if (!mXlibSurface || mXlibSurface->CairoStatus()) {
46 0 : return nullptr;
47 : }
48 :
49 0 : return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mXlibSurface, size);
50 : }
51 :
52 : void
53 0 : WindowSurfaceXRender::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
54 : {
55 0 : AutoTArray<XRectangle, 32> xrects;
56 0 : xrects.SetCapacity(aInvalidRegion.GetNumRects());
57 :
58 0 : for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
59 0 : const LayoutDeviceIntRect &r = iter.Get();
60 0 : XRectangle xrect = { (short)r.x, (short)r.y, (unsigned short)r.width, (unsigned short)r.height };
61 0 : xrects.AppendElement(xrect);
62 : }
63 :
64 0 : if (!mGC) {
65 0 : mGC = XCreateGC(mDisplay, mWindow, 0, nullptr);
66 0 : if (!mGC) {
67 0 : NS_WARNING("Couldn't create X11 graphics context for window!");
68 0 : return;
69 : }
70 : }
71 :
72 0 : XSetClipRectangles(mDisplay, mGC, 0, 0, xrects.Elements(), xrects.Length(), YXBanded);
73 :
74 0 : MOZ_ASSERT(mXlibSurface && mXlibSurface->CairoStatus() == 0,
75 : "Attempted to commit invalid surface!");
76 0 : gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
77 0 : gfx::IntSize size(bounds.XMost(), bounds.YMost());
78 0 : XCopyArea(mDisplay, mXlibSurface->XDrawable(), mWindow, mGC, bounds.x, bounds.y,
79 0 : size.width, size.height, bounds.x, bounds.y);
80 : }
81 :
82 : } // namespace widget
83 : } // namespace mozilla
|