* FuseSMB provides access to shared files and folders over SMB.
It features automatic discovery of servers and shares and
displays them as a folder hierarchy in a virtual volume on the
desktop
* Supports interactive authentication to access shares which require
login. Just open it, and a dialog pops up. Login data is stored in
BKeyStore.
* Comes with a network preferences add-on to easily enable and
configure it. No barbaric manual typing of mount commands required!
* Makes use of Haiku FUSE extensions to give custom MIME types with
icons for workgroup/share/server folders. Thanks again to humdinger
for designing the workgroup and share icons!
* Although the used libsmbclient only supports SMB protocol
version 1, performance is decent enough. Getting around ~75MiB/s
reading over a GbE link here
* Commit 0bec83a8 added const to the signatures of
pthread_mutex*_get*() functions. The declarations in
posix_error_mapper now didn't match that anymore, so the
extern C was lost, adding C++ mangling to the functions
from posix_error_mapper. This made linking applications with
posix_error_mapper fail.
* Last commit put the file-extension-to-MIME-type table and associated
code into a shared location. So now we can remove it from the FAT
and NTFS FS add-ons (they both had their own copy) and use the shared
one there as well, removing the code duplication.
* Add special handling for reading the BEOS:TYPE attribute to supply
on-the-fly fake MIME types for FUSE module filesystems, the same
way it's done in our FAT and NTFS FS modules
* Reuse the mime_ext_table which we already have and put it into a
shared location so we don't get further extra copies of it
* Implement reading extended file attributes in FUSE modules,
using getxattr()
getxattr() is a quite limited API, not allowing to specify a read
offset. So we read in the entire attribute value into a buffer and
store in the cookie. This shouldn't be a problem memory-wise, since
xattr implementions usually have limitations regarding attribute size
anyway, so it'll rarely be more than a few kilobytes.
* Writing, renaming, and removing attributes is not yet implemented
* Add a way for a FUSE module to supply Haiku-specific extensions.
This allows it to integrate better with Haiku while only requiring
minimal changes on the FUSE module itself.
* For now, there is only one extension: another function pointer for
"get_fs_info", which lets the FUSE module fill in an fs_info struct.
FUSE provides no good way to otherwise communicate extra information,
such as the volume flags (e.g. B_FS_IS_SHARED).
* A FUSE module can signal that it supports the Haiku extensions by
a) defining HAS_HAIKU_FUSE_EXTENSIONS before including the fuse
headers
b) setting the global variable gHasHaikuFuseExtensions to 1 in
its initialization
Otherwise, the Haiku extensions are completely invisible to the
FUSE module.
* Commit 337c4ccf introduced usage of plain memcpy in
get_next_frame_no_debugger(), when the frame is already
known to be on the kernel stack. However, it also needs
to check that the end of the frame is still within the
stack bounds. Otherwise this can cause a KDL if bp does
not point to a valid complete frame anymore and is
near a page boundary. Although with commit e477b10c such
cases should already be avoided, it's still safer to
check this here in case of e.g. analyzing broken stacks.
* No need to continue walking the stack when a zero return
address is found, only bogus frames will follow
* Fixes KDLs seen when using the system profiler, due to
a bug that will be fixed in the next commit...
* "ht" and "-ht" enable or disable the use of HT mode
(high throughput, 802.11n) for the wireless network device
* Analogous to the option with the same name in FreeBSD's ifconfig
* Disabling HT before associating with an AP is a workaround for
connection instability issues encountered with iprowifi4965
driver
* Painter::StrokeLine() has an optimization for lines which are
single pixel dots, i.e. identical start and end point and pen
size 1: it sets the pixel directly in the buffer, completely
bypassing the AGG base renderer.
This is a problem when inside a layer since this also bypasses
the low-level offset in the base renderer (which moves drawing
coordinates into the layer bitmap), causing an out-of-bounds
access.
* Fixes#12587
* When cloning a cached mask, we have to attach the
AGG rendering buffer of the new instance to the AGG clipped
mask object. Before, it was using the buffer description from
the clone source.. which can later disappear at any time.
* Fixes bug #12478
* Make getaddrinfo() and friends thread-safe by using the thread-safe
versions of the res functions.
* NetBSD offers two versions of the res functions: one in res_state.c
from the netresolv directory, defined as weak symbols. It is the
legacy version and only for single-threaded applications.
A thread-safe version of the functions is in res_state.c inside
their libpthread directory. An application that uses pthreads on
NetBSD will then use the non-weak symbols from the pthreads
library.
* On Haiku, the thread-safe version is now always used. The
res_state.c is taken from NetBSD's libpthread directory, and then
only struct _nres from the other file is added to it.
Please keep this in mind for future updates of netresolv, do not
accidentally replace it with the single-threaded version.
* This e.g. fixes WebPositive just hanging when opening websites
(even in situations where no IPv6-related problems apply), waiting
forever to resolve names.
* Fix wrong nesting of loops which are supposed to skip the first
(*cookie) number of elements and those with the wrong address
family
* With a start value of first = 0 (the usual case), the old code
would always just return the first element of the addrinfo list, no
matter which address family was actually requested
* The pointer mdt should point to the start of the contents of the
master data table. As defined in struct ATOM_MASTER_DATA_TABLE,
the content begins 4 bytes after the beginning of the table
(which in turn is ctx->data_table bytes from the start of the
AtomBIOS). The wrong parantheses in the cast moved the pointer
somewhere else completely.
* That this apparently worked on many cards is because the mdt
pointer in this function is used just to make sure that the
following dereference is not a NULL-pointer access.
The actual dereference is then done using the CU16() and CU8()
macros which do the casts correctly. However, it only worked when
the wrong pointer plus index lead to some byte which was, by
chance, not zero. For many chips, this was the case.
* For the AtomBIOS of a Radeon HD7850M (Heathrow Pro) it didn't work
out though and the driver couldn't parse tables. With this fix, it
now works on such chips as well.
* Also, fix the same problem in code for master command table.
* At least some nVidia HDA controllers do not acknowledge the CORB
read pointer reset, which is required by the spec (cf. HDA 1.0a
ch. 3.3.21). For these controllers, do not fail when acknowledge
is missing.
* Makes hda driver work for nVidia HDA controllers again, thus fixing
the regression pointed out in #10212.
* Some chipsets do not support bus-snooping for the HDA data
transfers. So, when trying to enable snooping, verify that the
setting was accepted.
* When snooping is not possible, set memory areas for audio buffers,
buffer descriptor lists and command ring-buffers as uncached to
ensure memory coherency with the HDA controller.
* This fixes KDLs during booting on some systems where snooping
is not supported (seen on two systems with AMD chipsets, maybe
applies to others as well).
After setting up the buffer descriptor list for a stream, it was a
gamble whether these writes would be visible to the HDA controller
when subsequently enabling the stream. On some boots it was unlucky
and then the HDA controller's DMA engine would go haywire and start
overwriting random kernel memory with audio input data. The
scheduler was usually the first victim and caused page fault KDLs
due to corrupted data structures.
* Do read-modify-write cycle to preserve bits marked as RsvdP in the
following registers: WAKEEN, CORBWP, CORBCTL, CORBSIZE, RIRBWP,
RINTCNT, RIRBCTL, RIRBSIZE.
* Spec requires software to wait for hardware to acknowledge the
reset by waiting for the bit to become set and then manually
unset it and again wait for it to become unset.
(cf. HDA spec 1.0a ch. 3.3.21)
* Also, do read-modify-write to protect preserved bits
* Radeon chips since Bonaire use a different PCI register base
address. Select the correct one depending on chipset generation
(values from Linux driver).
* Makes radeon_hd work for newer APUs/GPUs (tested with Kabini APU).
* Prefix lock functions with __ to mark them as private. Add
forwarding macros to keep existing code working.
* Avoids symbol name clashes with kernel lock APIs, occuring when
using kernellandemu-lib in userlandfs. Thanks to Ingo for the
suggestion.
* Base class needs to check this as well because the subclass might
not override it (e.g. InitParametersPanel).
* Fixes crash when trying to initialize partition map. Thanks to
jessicah for pointing this out.
* When the add-on provides no parameter editor, still add the set of
of default controls instead of just bailing out of the Init()
method.
* Before, DriveSetup never added the default controls in such cases
and simply showed an empty window. This happened when e.g. trying
to create a new partition inside an extended partition (because
ExtendedPartitionAddOn provides no parameter editor).
* Fixes#10569
* When determining the output link, look at the internal encoder in
the transmitter setup.
* Fixes getting no picture on digital output of certain systems.
* The rounding algorithm here expects to start with the 2 digits
after the decimal point in pll->feedbackDivFrac. Multiplying with
1000 instead of 100 filled it with 3 digits.
The last step then set the fractional part to zero because it was
still too large.
* The AMD-part of the add-on is supposed to reject some very old
models. However, a bug in the selection code caused it to reject
anything with model-number smaller 9 regardless of model-family.
This caused MTRR setup to not happen on many AMD CPUs and Haiku
being very slow on these machines.
* Fixes#10571
* BSecureSocket::CertificateVerificationFailed() took a BCertificate
instance by value as parameter.
BCertificate deletes internal data in its destructor. Passing an
object by value creates a copy, so the copy attempted to delete
the internal data again during its destruction.
This caused mail_daemon to crash here when it came across a failed
certificate.
* Fix: pass BCertificate object as reference.
* BWindow used to generate the B_MOUSE_IDLE events by sending a
delayed message with a one-shot BMessageRunner to itself.
Every creation and deletion of BMessageRunners causes synchronous
messaging between the application under the mouse cursor and the
registrar. This creates large amounts of calls to set_port_owner()
in the kernel whenever moving the mouse.
* Now, B_MOUSE_IDLE is sent by the cursor loop inside the app_server
instead. When the mouse wasn't moved for the tooltip delay time,
it inserts a B_MOUSE_IDLE message into the event stream.
* The tooltip delay thus becomes a system-wide constant and is not
configurable per-application anymore (no code currently in the
Haiku repo makes use of that anyhow).
* Replace ports list mutex with R/W-lock.
* Move team port list protection to separate array of mutexes.
Relieve contention on sPortsLock by removing Team::port_list from its
protected items. With this, set_port_owner() only needs to acquire the
sPortsLock for reading.
* Add another hash table holding the ports by name. Used by find_port()
so it doesn't have to iterate over the list anymore.
* Use slab-based memory allocator for port messages. sPortQuotaLock was
acquired on every message send or receive and was thus another point
of contention. The lock is not necessary anymore.
* Lock for port hashes and Port::lock are no longer locked in a nested
fashion to reduce chances of blocking other threads.
* Make operations concurrency-safe by adding an atomically accessed
Port::state which provides linearization points to port creation and
deletion. Both operations are now divided into logical and physical
parts, the logical part just updating the state and the physical part
adding/remove it to/from the port hash and team port list.
* set_port_owner() is the only remaining function which still locks
Port::lock and one or two of sTeamListLock[] in a nested fashion.
Since it needs to move the port from one team list to another and
change Port::owner, there's no way around.
* Ports are now reference counted to make accesses to already-deleted
ports safe.
* Should fix#8007.
* Optimized code path for bitmap drawing with bilinear interpolation
scaling was assuming that source bitmap is always at least 2 rows
in size.
* Fixes#12469: in webkit, scaled 1-pixel-high bitmaps often occur.
If the bitmap allocation is by chance aligned to a page end, access
to the non-existant second row crashes app_server.
* Add a lock which is acquired when reattaching/regenerating masks,
and also acquired for a cached mask before making a clone of it,
to prevent the clone from having an inconsistent state in
concurrent edge cases.
* Maybe fixes#12469
* If the same shape alpha mask is set again and again, we now keep
the rendered masks in a cache. On certain websites, WebKit sets
the same shape for clipping hundreds of times, which uses a lot
of time to render the masks.
* When a shape mask was generated, we put it into AlphaMaskCache.
The constructor for ShapeAlphaMask is made private and a factory
method is used for instantiation instead, which transparently
looks up in the cache whether a suitable mask was already generated
before (so the entire caching is encapsulated inside the AlphaMask
class).
* When taking a mask out of the cache, we still create a new
AlphaMask instance. However, the new instance will share the
mask bitmap with the previously generated instance (aside from
the rendering of their bitmap, AlphaMask instances are pretty
lightweight). Shape masks are only seen as identical when
their shape is the same, the inverse flag, and they have the
same parent mask.
* Cache is limited to a fixed size of currently 8 MiB, using a
simple random replacement scheme. An LRU scheme can be added in
the future if necessary. Counting of bytes for the cache size
includes parent masks of masks in the cache, even if the parent
itself is not cached. A reference counter for "indirect" cache
references keeps track of which masks are not part of the cache,
but still need to be added to the cache byte size.
* For now, only for ShapeAlphaMasks, other mask types can be added
as necessary.
* If there is an empty clipping region (invalid clipping) for the
current view, a new layer could still be started, but not ended
anymore. That's because unlike begin layer, end layer is handled in
_DispatchViewDrawingMessage (because it can do actual drawing)
and this method checks whether the clipping is valid and bails out
if it isn't.
* Add an exception for the AS_VIEW_END_LAYER command code to still
process it even when the clipping is invalid. The layer itself
can after all set a valid clipping later on when its command list
is played back. And even if it doesn't, we still have to play it
to make sure nested layers are cleaned up.
* Fixes the memory leak in #12460 where webkit creates
said situation: it had a layer open and then the closing was
ignored due to empty clipping. All subsequent layer calls created
nested layers in that one, hundreds of them, and their BPictures
contained bitmaps, quickly eating up and leaking hundreds of MiB
in app_server.
* When a layer has opacity 0, we can't just ignore it, we still
have to play back its picture, even if the drawing will never
appear on screen. This is because there might be nested layers
and if they don't get blended, their references are not released.
Also, it can be argued that state changes in the layer should be
applied even if the layer is invisible (if we ignore it there,
it would be inconsistent with other layers).
This edge case of invisible layers could be optimized further, but
it is rare enough anyway, so this should do.
* OffscreenCanvas was not deleting its DrawState. Found thanks to
the allocation tracking feature in libroot_debug (thanks mmlr!)
* Also a missing nothrow and a missing ref release in an error case
* Making the alpha masks independent of view size is a good thing,
however it turns out that I was too optimistic about the
consequences: webkit sometimes sets masks for the whole page, not
just the currently visible area. E.g. on Github diff views, it
was seen to set a clipping path which is about 1,000 x 10,000
pixels in size. Generating these huge masks eats up lots of memory
and time.
* We now clip the alpha masks to the current view size. This
introduces a dependency between mask and view again, however a
weaker one than it used to be before the mask rework. When the
view is enlarged, and the alpha mask was previously clipped during
rendering, we regenerate it at the new size. When the view is
shrunk however, we don't do anything and just keep the
now larger than necessary mask around (so we don't have to
regenerate again when the view is subsequently enlarged again --
except if it then becomes even larger than it used to be).
Changing the view origin is unaffected and still doesn't cause a
regenerate.
* BView::TranslateBy(), BView::ScaleBy() and BView::RotateBy()
allow to conveniently modify the current affine transformation.
This makes it unnecessary to first read the current transform,
modify it, and then set it again.
Uses the new Pre...() methods of BAffineTransform.
* Also, remove setting the transform "through" to the BView even
while recording a BPicture, as this now results in transforms
being applied more than once.
* The existing methods TranslateBy(), ScaleBy() and RotateBy()
transform the transformation. For a transform A, a point p,
and the temporary transform B (being applied by the methods),
this results in p' = B*(A*p) = (B*A)*p
This is not necessarily the desired result. Suppose A is a
translation and B a rotation, added by RotateBy(). Then B*A
means that the translation itself is rotated, so B moves the
coordinate origin itself, by rotating it around the original
origin of the coordinate system (top left view corner).
If we want to translate and then rotate around that *new* origin,
we need to multiply the transforms the other way around: A*B.
Three new methods PreTranslateBy(), PreScaleBy() and PreRotateBy()
implement this. They are later used as a base to add translatation/
scaling/rotation methods to BView which behave in the expected
ordering, similar to other graphic APIs.
* Add new clipping API for rectangles (ClipToRect, ClipToInverseRect)
and shapes (ClipToShape, ClipToInverseShape)
* Works with affine transforms and automatically switches from fast
region-based clipping to alpha-mask based clipping as necessary.
* Always self-intersecting, i.e. no state push required to further
narrow down the clipping region. All of the 4 new methods can be
mixed in any order.
* Add IsDilation() to BAffineTransform and Transformable which check
whether the transform is a dilation, i.e. consists of only
translation and/or scaling
Conflicts:
src/kits/interface/PicturePlayer.cpp
src/servers/app/ServerPicture.cpp
In addition, the following files were also adapted to master branch
BPicture changes during the merge:
src/kits/interface/PicturePlayer.h
src/servers/app/PictureBoundingBoxPlayer.cpp
* Refactor AlphaMask class to separate the mask from its source. This
allows use to not just a BPicture as source for a pixel alpha mask,
but also e.g. a BShape in the future (not yet implemented).
* For BPicture-based masks, use the PictureBoundingBoxPlayer to
determine the size of the resulting mask bitmap. The masks are now
drawn into bitmaps of this size (instead of the whole view size).
When alpha masks are stacked, their bounding rectangles intersect
(i.e. masks further up in the stack can never be larger than masks
lower in the stack). The bitmap of a mask always contains the state
of itself blended with all masks in the stack below it.
This also avoids frequent rerendering of the masks. They are now
independent of view size. When the view origin (in screen
coordinates) changes we only have to reattach the mask buffer,
without having to redraw it.
* The class UniformAlphaMask is used for simple masks with the same
alpha value in all pixels, it uses no mask bitmap at all.
Currently, it can only be used on its own and not be stacked
together with other mask types.
* Make test-app_server work again in a launch_daemon environment
* test_registrar gets a separate signature and port name again so the
host system can distinguish it from the system registrar
* AppServer is normally a BServer now, however, there can't be two
BApplications in one team. A class TestServerLoopAdapter is added,
which becomes the base class of AppServer instead of BServer when
compiling for libbe_test. It's an adapter class which looks towards
AppServer as it if was a BServer, but internally it is derived from
MessageLooper (like the old AppServer before the transition to
BServer).
This way, AppServer can stay a BServer in normal builds and it also
avoids having to use too many #ifdefs to distinguish the two
versions.
* Same concept as the previously exisiting drawing mode
implementations for e.g. pixel alpha overlay mode: when pattern
is solid, provide a separate mode implementation which does no
unnecessary pattern pixel lookups. This provides a considerable
speedup in composite mode when no stipple pattern is used.
* Add support for pixel alpha overlay mode in the optimized bilinear-
scaled bitmap drawing code of BitmapPainter.
For now, only BilinearDefault supports this. DrawBitmapBilinear
gets the colour type and draw mode as template parameters to
minimize code duplication and allow simple extension with further
pixel formats and modes.
Avoids, for this mode, fallback to the slower generic
AGG-pipeline-based version.
* Add another mode to DrawBitmapNoScale for drawing bitmaps using
B_OP_COPY with alpha masks. It behaves like the definition for
ClipToPicture from the BeBook: pixels with alpha = 0 are ignored,
pixels with any alpha > 0 are copied.
Before, this fell back to the slower generic AGG-pipeline-based
version.
* Some light refactoring
* To use alpha masks in optimized drawing code outside of the AGG
renderer pipeline, we need to allow access to the alpha mask's
underlying buffer:
- AlphaMask gets another method which returns its
clipped_alpha_mask
- clipped_alpha_mask gets a get_hspan() method which returns a span
of alpha values without combining it with anything
- Painter/PainterAggInterface store a pointer to the
clipped_alpha_mask (in addition to the AlphaMask's scanline
container)
* Extract bitmap drawing from Painter into separate class
Painter::BitmapPainter. This will allow to add new optimized
drawing modes without making Painter larger.
* BitmapPainter itself is further decomposed into separate
(method object) structs per drawing mode (currently, those are:
generic, no scale, nearest neighbor, bilinear). New optimized
implementations can be added by writing additional method objects
and calling them from BitmapPainter.
* DrawBitmapNoScale and DrawBitmapBilinear are implemented using
CRTP. This removes the function pointer in the 'no scale' version,
which was previously used to select the row copy type. In the
bilinear version it untangles the three variants (default,
low filter ratio, SIMD) into separate methods.
* While BitmapPainter is a nested class in Painter, the specialized
method objects are not. Instead, the AGG-specific data fields from
Painter are moved into a new struct PainterAggInterface. This
struct is passed to the method objects and allows them to access
the Painter's AGG renderer/rasterizer/scanline containers/etc.
Alternatives would be to make all the involved structs friends
of Painter, or nesting them all, or exposing all of Painter's
internals via getter methods -- all of these would be quite messy.
The details of the bitmap painting implementations are
intentionally hidden from Painter: there is no need for it to
know about their internals -- it does not even know their type
names. (Nesting or making them friend would expose their type
names to Painter.)
Furthermore, there is another level of information hiding between
BitmapPainter and the DrawBitmap[...] method objects.
BitmapPainter itself only needs to decide that it uses e.g. the
bilinear version. It has no knowledge that DrawBitmapBilinear is
internally made out of several structs implementing specially
optimized versions.
* Refactoring only, no functional change intended. Performance
should be unaffected.
* For better performance, we allow doing drawing mode changes
(and thus, B_OP_COPY) again when inside an opaque layer which
has only other opaque layers below it in the layer stack.
As soon as the first non-opaque layer turns up in the stack, the
drawing mode will be locked to alpha composite mode, until this
layer stack is ended entirely.
This allows using B_OP_COPY in many cases as used by WebKit.
* In the long term it would be nice to get rid of the drawing-mode
lock altogether, however that would need some larger refactoring
work in Painter (i.e. remove the offsetting from renderer_region
again and instead implement an "exit-level transform" (support
for offsets is enough) in Painter which is applied after all other
transforms).
* Opaque layers (opacity = 255) don't need to use an intermediate
bitmap (and everything that comes with it) for drawing at all,
they can just directly draw onto the underlying canvas or layer.
(WebKit likes to use plenty of opaque layers)
* Invisible layers (opacity = 0) can simply be ignored.
* Add new methods
BView::BeginLayer(uint8 opacity)
BView::EndLayer()
* All drawing between begin and end of a layer is redirected onto an
intermediate bitmap. When ending the layer, this bitmap is
composited onto the view with the opacity given when the layer was
started.
* Layers can be nested arbitrarily and will be blended onto each
other in order. There can also be any arbitrary interleaving of
layer begin/end and drawing operations.
* Internally, drawing commands are redirected into a BPicture between
BeginLayer and EndLayer (but client code need not know or care
about this). Client code can also start/end other BPictures while
inside a layer.
* Uses the PictureBoundingBoxPlayer to determine the size of the
layer bitmap before allocating and drawing into it, so it does not
allocate more memory than necessary and -- more importantly -- it
will not alpha-composite more pixels than necessary.
* Drawing mode is always set to B_OP_ALPHA, blend mode to
(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE) while inside layers. This is
necessary for (a) correct compositing output and (b) for
redirection of drawing into the intermediate bitmap, which uses the
renderer_region offset (in B_OP_COPY, the Painter does not use the
AGG renderer methods, it directly accesses the pixel data. This
would access out-of-bounds without the offset, so B_OP_COPY cannot
be allowed.)
To ensure these modes aren't changed, BView::SetDrawingMode()
and BView::SetBlendingMode() are ignored while inside a layer.
* The main motivation behind this new API is WebKit, which internally
expects such a layers functionality to be present. A performant and
reusable implementation of this functionality can only be done
server-side in app_server.
* agg::renderer_region gets an extra feature which allows to
optionally shift the coordinates by a specified offset.
* This allows to shift coordinates at the lowest level, even below
the transformations done by BAffineTransform (which happen in the
painter, right before rasterization).
Needed for layers support: shifts the origin of the layer bitmaps
to their position in the view while keeping all transformations
(BView origin/scale transforms as well as BAffineTransforms)
intact. The offset for the layer bitmaps within their parent view
is determined by the bounding box and is then fixed, it must not
be altered while the layer's BPicture is played into the bitmap.
If this offset were added to the BView origin or as translation in
the BAffineTransform, it would be further transformed by the BView
scale or the other affine transform parameters. Thus, we need
another low-level offset mechanism which is even below
BAffineTransform's transformations.
* Allow shifting the offset of alpha masks without changing the size.
Ideally, we only need to reattach the buffer in the shifted
position, saving the work of reallocating and redrawing the mask
picture. Needed for layers support.
* Another constructor for AlphaMask allows creating a mask with no
picture, it will simply be a single uniform alpha value over the
whole mask.
* No need to even allocate a buffer in this case, we can just use
the feature of clipped_alpha_mask to define an opacity for outside
the mask, and set the buffer size to zero.
* New method DrawState::SetTransformEnabled allows to temporarily
disable all BAffineTransforms in the state stack (up to 'this').
Later, the same method can be used to reenable the transforms.
Needed for layers support: when drawing the finished layer bitmap
onto the view, the affine transforms must not be applied again --
they have already been applied while drawing the bitmap's contents.