History log of /frameworks/base/libs/hwui/PatchCache.cpp
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)

Test: none, it's unused code
253f2c213f6ecda63b6872aee77bd30d5ec07c82 29-Sep-2016 Romain Guy <romainguy@google.com> Linear blending, step 1

NOTE: Linear blending is currently disabled in this CL as the
feature is still a work in progress

Android currently performs all blending (any kind of linear math
on colors really) on gamma-encoded colors. Since Android assumes
that the default color space is sRGB, all bitmaps and colors
are encoded with the sRGB Opto-Electronic Conversion Function
(OECF, which can be approximated with a power function). Since
the power curve is not linear, our linear math is incorrect.
The result is that we generate colors that tend to be too dark;
this affects blending but also anti-aliasing, gradients, blurs,
etc.

The solution is to convert gamma-encoded colors back to linear
space before doing any math on them, using the sRGB Electo-Optical
Conversion Function (EOCF). This is achieved in different
ways in different parts of the pipeline:

- Using hardware conversions when sampling from OpenGL textures
or writing into OpenGL frame buffers
- Using software conversion functions, to translate app-supplied
colors to and from sRGB
- Using Skia's color spaces

Any type of processing on colors must roughly ollow these steps:

[sRGB input]->EOCF->[linear data]->[processing]->OECF->[sRGB output]

For the sRGB color space, the conversion functions are defined as
follows:

OECF(linear) :=
linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1/2.4) * 1.055) - 0.055

EOCF(srgb) :=
srgb <= 0.04045 ? srgb / 12.92 : pow((srgb + 0.055) / 1.055, 2.4)

The EOCF is simply the reciprocal of the OECF.
While it is highly recommended to use the exact sRGB conversion
functions everywhere possible, it is sometimes useful or beneficial
to rely on approximations:

- pow(x,2.2) and pow(x,1/2.2)
- x^2 and sqrt(x)

The latter is particularly useful in fragment shaders (for instance
to apply dithering in sRGB space), especially if the sqrt() can be
replaced with an inversesqrt().

Here is a fairly exhaustive list of modifications implemented
in this CL:

- Set TARGET_ENABLE_LINEAR_BLENDING := false in BoardConfig.mk
to disable linear blending. This is only for GLES 2.0 GPUs
with no hardware sRGB support. This flag is currently assumed
to be false (see note above)
- sRGB writes are disabled when entering a functor (WebView).
This will need to be fixed at some point
- Skia bitmaps are created with the sRGB color space
- Bitmaps using a 565 config are expanded to 888
- Linear blending is disabled when entering a functor
- External textures are not properly sampled (see below)
- Gradients are interpolated in linear space
- Texture-based dithering was replaced with analytical dithering
- Dithering is done in the quantization color space, which is
why we must do EOCF(OECF(color)+dither)
- Text is now gamma corrected differently depending on the luminance
of the source pixel. The asumption is that a bright pixel will be
blended on a dark background and the other way around. The source
alpha is gamma corrected to thicken dark on bright and thin
bright on dark to match the intended design of fonts. This also
matches the behavior of popular design/drawing applications
- Removed the asset atlas. It did not contain anything useful and
could not be sampled in sRGB without a yet-to-be-defined GL
extension
- The last column of color matrices is converted to linear space
because its value are added to linear colors

Missing features:
- Resource qualifier?
- Regeneration of goldeng images for automated tests
- Handle alpha8/grey8 properly
- Disable sRGB write for layers with external textures

Test: Manual testing while work in progress
Bug: 29940137

Change-Id: I6a07b15ab49b554377cd33a36b6d9971a15e9a0b
fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58 12-May-2016 sergeyv <sergeyv@google.com> Move gl calls from PatchCache to MeshState

bug:27358166
Change-Id: I5f544f497e9480e64faa2ddd369eb16318e82dc3
48a8f431fa52ae2ee25ffba9d20676f03bb710ff 06-Feb-2016 Chris Craik <ccraik@google.com> Move several property queries to Properties class

bug:17478770

This removes a lot of redundant property query code, and puts the
queries all in one place, so defining them automatically will be simpler
in the future.

Change-Id: I0428550e6081f07bc6554ffdf73b22284325abb8
5a4690bf26932c0d6940e4af8516d920e09ae81a 14-Jul-2015 Chris Craik <ccraik@google.com> Clean up unncessary defines

LOG_TAG and TRACE_TAG are already defined in the makefile

Change-Id: I9e53e3dacbe018441edd74cb7c8c90846defee74
8820fd1d82acaefda98ae73ccf61413d5044f9f3 03-Mar-2015 Chris Craik <ccraik@google.com> Patch cleanup, reenable Patch Glops

bug:19597454

Change-Id: If12b95e83588b81a553210cd8c2437c6c771073a
96a5c4c7bab6718524de7253da8309143ab48bef 28-Jan-2015 Chris Craik <ccraik@google.com> Move more GL state management to RenderState and its directory

d41c4d8c732095ae99c955b6b82f7306633004b1 06-Jan-2015 Chris Craik <ccraik@google.com> Add overrides and switch to nullptr keyword for all files

Adds remaining missing overrides and nullptr usages, missed due to
an extreme failure in tool usage.

2dc236b2bae13b9a0ed9b3f7320502aecd7983b3 15-Oct-2014 Tom Hudson <tomhudson@google.com> Clean up physical coupling

Narrow the use of #include directives in hwui, replacing with forward
declarations where straightforward. Speeds compiles; doesn't do any
restructuring of code.

Change-Id: Icac2baffb5896f55d8c6718e9bd9d4bfa02d3ca0
6056e1027107aaa15f51a5ed775ff14c6b664ca3 04-Feb-2014 Jens Gulin <jens.gulin@sonymobile.com> Solve three memory leaks related to PatchCache

A Patch can be fairly large, holding bitmap data, but
is also frequently leaked which adds to the severity.
The feature is used in many important processes such
as Home, SystemUI and Chrome.

The following leaks are solved:

1. The Patch itself was not always freed.
PatchCache::removeDeferred() can mark patches to be
cared for by PatchCache::clearGarbage(). But
mCache.remove() would only destroy the container
and the pointer, not the Patch object itself.

2. The vertices stored in the Patch at Patch::createMesh()
would always leak. The empty/default destructor in Patch
would not properly destroy "vertices" since it's just a
pointer.

3. A BufferBlock that's added to the mFreeBlocks
in PatchCache could leak. The leak happened when a
patch later needed the entire free block, because the
object was removed from the list but never deleted
in PatchCache::setupMesh().

Change-Id: I41e60824479230b67426fc546d3dbff294c8891f
36fad8f6fcfbc2087b910600ed5a6f9741177d00 09-Jan-2014 Sangkyu Lee <sk82.lee@lge.com> Fix graphics corruption caused by HWUI caches

Some caches(PatchCache, TextureCache, PathCache) for HWUI
uses deferred removal for their cache entries even though
actual resource objects are immediately freed by
ResourceCache.
For this reason, the uniqueness of a resource address in
the caches is not guaranteed in specific cases.
(Because malloc() can return the same address when malloc()
and free() called very frequently.)

So it can be possible the cache have two cache entries for
two different resources but the same memory address.
(Of course one of the resources is already freed.)
It also can be possible mGarbage vector in PatchCache has
blocks in the free block list and graphics corruption.
(Deferred removal was implmeneted based on an assumption of

So this patch makes sure resource objects are freed after
the resources are removed from the caches to guarantee
the uniqueness of a resource address and prevent graphics
corruption.

Change-Id: I040f033a4fc783d2c4bc04b113589657c36fb15b
Signed-off-by: Sangkyu Lee <sk82.lee@lge.com>
e3b0a0117a2ab4118f868a731b238fe8f2430276 27-Jun-2013 Romain Guy <romainguy@google.com> Refcount 9-patches and properly handle GC events

This change adds refcounting of Res_png_9patch instances, the native
data structure used to represent 9-patches. The Dalvik NinePatch class
now holds a native pointer instead of a Dalvik byte[]. This pointer
is used whenever we need to draw the 9-patch (software or hardware.)

Since we are now tracking garbage collection of NinePatch objects
libhwui's PatchCache must keep a list of free blocks in the VBO
used to store the meshes.

This change also removes unnecessary instances tracking from
GLES20DisplayList. Bitmaps and 9-patches are refcounted at the
native level and do not need to be tracked by the Dalvik layer.

Change-Id: Ib8682d573a538aaf1945f8ec5a9bd5da5d16f74b
03c00b5a135e68d22ca5bb829b899ebda6ed7e9d 21-Jun-2013 Romain Guy <romainguy@google.com> Batch 9-patches in a single mesh whenever possible

This change also fixes the way batched bitmaps were handled
inside a layer. The layer is now correctly dirtied to minimize
the amount of pixels to blend.

Fix alpha, mode and opaque computations for DrawPatchOp.

Change-Id: I1b6cd581c0f0db66c1002bb4fb1a9811e55bfa78
4c2547fa9244e78115cde0a259291053108c3dc7 12-Jun-2013 Romain Guy <romainguy@google.com> Avoid 9patch cache lookups when possible

This optimization saves up to 0.3ms per frame on the Play Store's
front page, on a Nexus 4 device.

Change-Id: Iaa4ef33c6e3b37e175efd5b9eea9ef59b43f14f3
7d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18 28-May-2013 Romain Guy <romainguy@google.com> Re-initialize the 9patch cache if cleared with onTrimMemory

The 9aptch cache was reinitialized after destroying/recreating
the EGL context but not after clearing it during a normal
memory trim.

Change-Id: If6155bfc8a62439e9878bc742a4766b3bd6c6aec
1f8a0db348f6c7bf2d1f55065472c913677f3d69 06-May-2013 Romain Guy <romainguy@google.com> Remove stray log

3b748a44c6bd2ea05fe16839caf73dbe50bd7ae9 18-Apr-2013 Romain Guy <romainguy@google.com> Pack preloaded framework assets in a texture atlas

When the Android runtime starts, the system preloads a series of assets
in the Zygote process. These assets are shared across all processes.
Unfortunately, each one of these assets is later uploaded in its own
OpenGL texture, once per process. This wastes memory and generates
unnecessary OpenGL state changes.

This CL introduces an asset server that provides an atlas to all processes.

Note: bitmaps used by skia shaders are *not* sampled from the atlas.
It's an uncommon use case and would require extra texture transforms

WHAT IS THE ASSETS ATLAS

The "assets atlas" is a single, shareable graphic buffer that contains
all the system's preloaded bitmap drawables (this includes 9-patches.)
The atlas is made of two distinct objects: the graphic buffer that
contains the actual pixels and the map which indicates where each
preloaded bitmap can be found in the atlas (essentially a pair of
x and y coordinates.)

HOW IS THE ASSETS ATLAS GENERATED

Because we need to support a wide variety of devices and because it
is easy to change the list of preloaded drawables, the atlas is
generated at runtime, during the startup phase of the system process.

There are several steps that lead to the atlas generation:

1. If the device is booting for the first time, or if the device was
updated, we need to find the best atlas configuration. To do so,
the atlas service tries a number of width, height and algorithm
variations that allows us to pack as many assets as possible while
using as little memory as possible. Once a best configuration is found,
it gets written to disk in /data/system/framework_atlas

2. Given a best configuration (algorithm variant, dimensions and
number of bitmaps that can be packed in the atlas), the atlas service
packs all the preloaded bitmaps into a single graphic buffer object.

3. The packing is done using Skia in a temporary native bitmap. The
Skia bitmap is then copied into the graphic buffer using OpenGL ES
to benefit from texture swizzling.

HOW PROCESSES USE THE ATLAS

Whenever a process' hardware renderer initializes its EGL context,
it queries the atlas service for the graphic buffer and the map.

It is important to remember that both the context and the map will
be valid for the lifetime of the hardware renderer (if the system
process goes down, all apps get killed as well.)

Every time the hardware renderer needs to render a bitmap, it first
checks whether the bitmap can be found in the assets atlas. When
the bitmap is part of the atlas, texture coordinates are remapped
appropriately before rendering.

Change-Id: I8eaecf53e7f6a33d90da3d0047c5ceec89ea3af0
9935abceea10df337969f08cce05b7c02bb1eb19 16-Feb-2013 Chris Craik <ccraik@google.com> Correct PatchCache comparison logic

Change-Id: I3d0832505b5380bfa362863b39e09dd10f792582

We now use the same mechanism to compare keys everywhere in libhwui.

Change-Id: I8b3cb25b13f4f38eb6f12aed0356f796a773617c
Bug #7970966

The bug described in #7970966 should normally never happen but just in
case, change the detection code to be more robust.

Change-Id: I7040a6087590e34abe8803cb8f83f051d77f3944
6f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cd 30-Nov-2010 Romain Guy <romainguy@google.com> Update 9patch structure when rendering with different divs/colors.
Bug #3221488

03750a067e818ca7fbd0f590e2ff6a8fded21e6c 18-Oct-2010 Romain Guy <romainguy@google.com> Use VBOs to render most geometries.

Change-Id: I4360dc4fe5693ab425450c107282b2c22db4dca7

Change-Id: If3e62e18b8e0dbde8a22f8ede2889b86500a4dc2

This change detects empty quads in 9patches and removes them from
the mesh to avoid unnecessary blending.

Change-Id: I4500566fb4cb6845d64dcb59b522c0be7a0ec704
21b028a44f3e0bd9b0f0432b8b92c45f661d22a4 09-Oct-2010 Romain Guy <romainguy@google.com> Move GenerationCache to the utils directory.

Change-Id: I210ffa8f1d76a102bb7d971c649c20a74d03fbe6
2728f961614a385df1f056fc24803a9f65c90fab 09-Oct-2010 Romain Guy <romainguy@google.com> Don't update 9patches on every frame.

Change-Id: I7ffb2365f83e0453e7d0a0cdcb3fc9308b305238
4aa90573bbf86db0d33a3a790c5dbd0d93b95cfe 27-Sep-2010 Romain Guy <romainguy@google.com> Adding display lists to the GL renderer (checkpoint.)

Change-Id: Iaa49757600a53b39369dbb23f8c3feab282518e6
fb8b763f762ae21923c58d64caa729b012f40e05 24-Aug-2010 Romain Guy <romainguy@google.com> Use only one GL context per process, share chaches.