List items
Items from the current list are shown below.
Blog
29 Oct 2023 : Day 74 #
That extra hour was worth the wait. I've not yet decided exactly how I spent it (possibly asleep, possibly fixing my Hue Hub) but it felt good to have enough time for both, and now it feels like it's the middle of the night, but it's actually only six thirty in the evening.
So today I'm continuing to go deeper and deeper into the rendering code. I've now got as far as nsCSSBorderRenderer::DrawBorders(). This is one of the methods that's called to render a bordered rectangle. I'm rendering a page that contains such objects and the breakpoint is hit on both ESR 78 and ESR 91.
The method then makes lots of decisions about exactly what it's going to render: are all the borders the same? Do they have zero thickness? Are they solid? Things like that.
Eventually we get to the point where an actual rectangle is going to be plotted:
So I'm stepping inside the method on ESR 91, from which it seems to be the case that it's the version in DrawTarget from 2D.h:
If we step through on either ESR 78 or ESR 91 we get to the same place:
So that's it for tonight! Sleep well.
For all the other entries in my developer diary, check out the Gecko-dev Diary page.
So today I'm continuing to go deeper and deeper into the rendering code. I've now got as far as nsCSSBorderRenderer::DrawBorders(). This is one of the methods that's called to render a bordered rectangle. I'm rendering a page that contains such objects and the breakpoint is hit on both ESR 78 and ESR 91.
The method then makes lots of decisions about exactly what it's going to render: are all the borders the same? Do they have zero thickness? Are they solid? Things like that.
Eventually we get to the point where an actual rectangle is going to be plotted:
mDrawTarget->FillRect(GetCornerRect(corner), ColorPattern(ToDeviceColor(color)));But what is mDrawTarget and which version of FillRect() is being called (there appear to be at least 18 to choose from). It looks like it should be an easy question: just check what type mDrawTarget is. But with multiple inheritance and virtual methods it's easier said than done. It can be easier to do at runtime with a debugger than by manual inspection of the code, in fact.
So I'm stepping inside the method on ESR 91, from which it seems to be the case that it's the version in DrawTarget from 2D.h:
(gdb) explore *mDrawTarget The value of '*mDrawTarget' is of type 'nsCSSBorderRenderer::DrawTarget' which is a typedef of type 'mozilla::gfx::DrawTarget' The value of '*mDrawTarget' is a struct/class of type 'mozilla::gfx::DrawTarget' with the following fields: mozilla::external::AtomicRefCounted<mozilla::gfx::DrawTarget> = <Enter 0 to explore this base class of type 'mozilla:: external::AtomicRefCounted<mozilla::gfx::DrawTarget>'> mUserData = <Enter 1 to explore this field of type 'mozilla::gfx::UserData'> mTransform = <Enter 2 to explore this field of type 'mozilla::gfx::Matrix'> mOpaqueRect = <Enter 3 to explore this field of type 'mozilla::gfx::IntRect'> mTransformDirty = true .. (Value of type 'bool') mPermitSubpixelAA = true .. (Value of type 'bool') mFormat = mozilla::gfx::SurfaceFormat::B8G8R8X8 .. (Value of type 'mozilla::gfx::SurfaceFormat') Enter the field number of choice:But as I mentioned the method is virtual and the above doesn't preclude it being overridden. So let's try to step inside it to see where we end up.
(gdb) n 3217 mDrawTarget->FillRect(GetCornerRect(corner), (gdb) n 3218 ColorPattern(ToDeviceColor(color))); (gdb) n 3217 mDrawTarget->FillRect(GetCornerRect(corner), (gdb) s mozilla::gfx::DrawOptions::DrawOptions (aAntialiasMode=mozilla::gfx:: AntialiasMode::DEFAULT, aCompositionOp=mozilla::gfx::CompositionOp::OP_OVER, aAlpha=1, this=0x7f9f3dfa90) at ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/gfx/2D.h:124 124 ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/gfx/2D.h: No such file or directory. (gdb) n nsCSSBorderRenderer::DrawBorders (this=this@entry=0x7f9f3dfc20) at /usr/src/debug/xulrunner-qt5-91.9.1-1.aarch64/layout/painting/ nsCSSRenderingBorders.cpp:3219 3219 continue;That's a mess. It's mostly a mess because there are four method calls essentially all on the same line as the FillRect() call that we're interested in, so we want to stop over three and into one of them:
- FillRect() (step into).
- GetCornerRect() (step over).
- ColorPattern() (step over).
- ToDeviceColor() (step over).
(gdb) b FillRect Breakpoint 3 at 0x7ff2858a58: FillRect. (25 locations) (gdb) c Continuing. Thread 10 "GeckoWorkerThre" hit Breakpoint 3, mozilla::gfx::DrawTargetTiled:: FillRect (this=0x7fb9250c10, aRect=..., aPattern=..., aDrawOptions=...) at /usr/src/debug/xulrunner-qt5-78.15.1+git33.2-1.21.1.jolla.aarch64/gfx/2d/ DrawTargetTiled.cpp:221 221 const DrawOptions& aDrawOptions) { (gdb)Happily this gives us what we need: it's the FillRect() method from DrawTargetTiled. This is what that method looks like:
void DrawTargetTiled::FillRect(const Rect& aRect, const Pattern& aPattern, const DrawOptions& aDrawOptions) { Rect deviceRect = mTransform.TransformBounds(aRect); for (size_t i = 0; i < mTiles.size(); i++) { if (!mTiles[i].mClippedOut && deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, mTiles[i].mTileOrigin.y, mTiles[i].mDrawTarget->GetSize().width, mTiles[i].mDrawTarget->GetSize().height))) { mTiles[i].mDrawTarget->FillRect(aRect, aPattern, aDrawOptions); } } }On ESR 91 we get something very similar:
(gdb) b FillRect Breakpoint 5 at 0x7fba5084ec: FillRect. (16 locations) (gdb) c Continuing. Thread 8 "GeckoWorkerThre" hit Breakpoint 5, mozilla::gfx::DrawTargetTiled:: FillRect (this=0x7f88dd55f0, aRect=..., aPattern=..., aDrawOptions=...) at /usr/src/debug/xulrunner-qt5-91.9.1-1.aarch64/gfx/2d/DrawTargetTiled.cpp:221 221 const DrawOptions& aDrawOptions) { (gdb)That's all encouraging and takes us a bit closer.
If we step through on either ESR 78 or ESR 91 we get to the same place:
(gdb) n 222 Rect deviceRect = mTransform.TransformBounds(aRect); (gdb) n 223 for (size_t i = 0; i < mTiles.size(); i++) { (gdb) n 224 if (!mTiles[i].mClippedOut && (gdb) n 313 obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h: No such file or directory. (gdb) n 228 mTiles[i].mDrawTarget->GetSize().height))) { (gdb) n 225 deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, (gdb) n 229 mTiles[i].mDrawTarget->FillRect(aRect, aPattern, aDrawOptions); (gdb) c Continuing. Thread 10 "GeckoWorkerThre" hit Breakpoint 3, mozilla::gfx::DrawTargetSkia:: FillRect (this=0x7fb8f8a3c0, aRect=..., aPattern=..., aOptions=...) at gfx/2d/DrawTargetSkia.cpp:775 775 const DrawOptions& aOptions) { (gdb)The DrawTargetSkia::FillRect() method is more complex, but eventually calls this:
mCanvas->drawRect(rect, paint.mPaint);Breakpointing on that takes us another step closer:
(gdb) c Continuing. [Switching to LWP 20030] Thread 10 "GeckoWorkerThre" hit Breakpoint 6, SkCanvas::drawRect (this=0x7fb90a72a0, r=..., paint=...) at gfx/skia/skia/src/core/SkCanvas.cpp:1803 1803 void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { (gdb) c Continuing. Thread 10 "GeckoWorkerThre" hit Breakpoint 6, SkBitmapDevice::drawRect (this=0x7fbb044a40, r=..., paint=...) at gfx/skia/skia/src/core/SkBitmapDevice.cpp:364 364 void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) { (gdb) c Continuing. Thread 10 "GeckoWorkerThre" hit Breakpoint 6, SkDraw::drawRect (paint=..., rect=..., this=0x7fde8d2d98) at gfx/skia/skia/src/core/SkDraw.h:42 42 this->drawRect(rect, paint, nullptr, nullptr); (gdb)This takes us to the SkDraw::drawRect() method:
void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint, const SkMatrix* paintMatrix, const SkRect* postPaintRect)The code reaches exactly the same place on ESR 78 and ESR 91. This seems like a good place to stop for the night. It'll take me a while to carefully read through this method to figure out what it's doing. It's also a good place to pause since putting a breakpoint on this method will allow me to easily return to this point tomorrow as well.
So that's it for tonight! Sleep well.
For all the other entries in my developer diary, check out the Gecko-dev Diary page.
Comments
Uncover Disqus comments