2010-06-16 18:44:05 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2010 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2010-10-27 18:57:51 -07:00
|
|
|
#ifndef ANDROID_HWUI_OPENGL_RENDERER_H
|
|
|
|
#define ANDROID_HWUI_OPENGL_RENDERER_H
|
2010-06-24 19:30:36 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
#include "CanvasState.h"
|
|
|
|
#include "Debug.h"
|
|
|
|
#include "Extensions.h"
|
|
|
|
#include "Matrix.h"
|
|
|
|
#include "Program.h"
|
|
|
|
#include "Rect.h"
|
|
|
|
#include "Snapshot.h"
|
|
|
|
#include "UvMapper.h"
|
|
|
|
#include "Vertex.h"
|
|
|
|
#include "Caches.h"
|
|
|
|
#include "utils/PaintUtils.h"
|
|
|
|
|
2010-06-24 19:30:36 -07:00
|
|
|
#include <GLES2/gl2.h>
|
|
|
|
#include <GLES2/gl2ext.h>
|
2010-06-22 13:11:24 -07:00
|
|
|
|
2010-06-29 21:05:21 -07:00
|
|
|
#include <SkBitmap.h>
|
2013-12-10 12:28:58 -05:00
|
|
|
#include <SkCanvas.h>
|
|
|
|
#include <SkColorFilter.h>
|
2015-08-20 16:07:54 -04:00
|
|
|
#include <SkDrawLooper.h>
|
2010-06-23 17:47:49 -07:00
|
|
|
#include <SkMatrix.h>
|
2010-06-29 21:05:21 -07:00
|
|
|
#include <SkPaint.h>
|
2010-07-16 14:12:24 -07:00
|
|
|
#include <SkRegion.h>
|
2010-06-22 13:11:24 -07:00
|
|
|
#include <SkXfermode.h>
|
2010-06-16 18:44:05 -07:00
|
|
|
|
2014-03-31 13:52:39 -04:00
|
|
|
#include <utils/Blur.h>
|
2011-01-10 14:10:36 -08:00
|
|
|
#include <utils/Functor.h>
|
2010-06-22 18:56:38 -07:00
|
|
|
#include <utils/RefBase.h>
|
2012-04-23 18:22:09 -07:00
|
|
|
#include <utils/SortedVector.h>
|
2010-06-22 18:56:38 -07:00
|
|
|
|
2011-10-12 13:48:51 -07:00
|
|
|
#include <cutils/compiler.h>
|
|
|
|
|
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
in the GL shaders.
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
2013-04-17 18:54:38 -07:00
|
|
|
#include <androidfw/ResourceTypes.h>
|
|
|
|
|
2015-07-29 16:48:58 -07:00
|
|
|
#include <vector>
|
|
|
|
|
Inspect SkShader to determine hw shader.
Instead of duplicating internal info about SkShader, inspect the
SkShader installed on the SkPaint.
core/java/android/view/GLES20Canvas.java:
Remove setupModifiers, nResetModifiers, and nSetupShader.
core/jni/android/graphics/Shader.cpp:
Remove calls to create/destroy the (previously) attached SkiaShader.
core/jni/android_view_GLES20Canvas.cpp:
Remove native code for setupShader and resetModifiers.
graphics/java/android/graphics/BitmapShader.java:
graphics/java/android/graphics/ComposeShader.java:
graphics/java/android/graphics/LinearGradient.java:
graphics/java/android/graphics/RadialGradient.java:
graphics/java/android/graphics/Shader.java:
graphics/java/android/graphics/SweepGradient.java:
Remove code keeping track of native SkiaShader.
libs/hwui/Caches.h:
Include Extensions.h.
libs/hwui/DeferredDisplayList.cpp:
Compare shaders on the paint, instead of on DrawModifiers.
libs/hwui/DisplayList.cpp:
libs/hwui/DisplayList.h:
Remove vector of SkiaShaders.
libs/hwui/DisplayListOp.h:
Access the SkShader on mPaint.
Remove SetupShaderOp and ResetShaderOp.
libs/hwui/DisplayListRenderer.cpp:
libs/hwui/DisplayListRenderer.h:
Remove resetShader, setupShader, refShader, and mShaderMap.
libs/hwui/FontRenderer.cpp:
Pass SkShader to setupDrawShader and setupDrawShaderUniforms.
libs/hwui/OpenGLRenderer.cpp:
libs/hwui/OpenGLRenderer.h:
Add LayerShader, a class inheriting from SkShader, to mimic the
behavior of SkiaLayerShader. Unlike SkiaLayerShader, it can be set on
the SkPaint so it can be inspected later.
Set a LayerShader instead of a SkiaLayerShader.
setupDrawShader and setupDrawShaderUniforms now inspect an SkShader
passed in.
Inspect SkShader instead of mDrawModifiers.mShader.
Remove resetShader and setupShader.
setupDrawColorUniforms now takes a boolean indicating whether there is
a shader.
Add an inline function for accessing the SkShader on an SkPaint.
In setupDrawBlending(Layer*, bool), do not check the shader (which will
never be set), but do check whether the color filter may change the
alpha (newly fixed behavior).
In setupDrawBlending(SkPaint, ...), check the SkShader and whether the
color filter affects alpha (the latter is new behavior).
libs/hwui/Renderer.h:
Remove pure virtual functions setupShader and resetShader.
libs/hwui/ResourceCache.cpp:
libs/hwui/ResourceCache.h:
Remove functions for refing/unrefing shaders.
libs/hwui/SkiaShader.cpp:
libs/hwui/SkiaShader.h:
Much of this code was redundant and has been removed.
Convert structs into class with nothing but static functions for
calling describe/setupProgram.
libs/hwui/TextureCache.cpp:
libs/hwui/TextureCache.h:
Use the SkPixelRef as the key to the bitmap Lru cache, since shader
inspection will provide a different SkBitmap pointer (though it will
hold the correct SkPixelRef with the correct generation ID).
tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java:
tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java:
Update manual test to have more shaders: radial, sweep, compose,
invalid compose.
BUG:10650594
Change-Id: Iaa7189178bda1c55f96da044d2a9fa602ba36034
2014-05-05 12:50:38 -04:00
|
|
|
class SkShader;
|
|
|
|
|
2010-06-16 18:44:05 -07:00
|
|
|
namespace android {
|
2010-06-24 19:30:36 -07:00
|
|
|
namespace uirenderer {
|
2010-06-16 18:44:05 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
enum class DrawOpMode {
|
|
|
|
kImmediate,
|
|
|
|
kDefer,
|
|
|
|
kFlush
|
|
|
|
};
|
|
|
|
|
2013-12-26 15:13:13 -08:00
|
|
|
class DeferredDisplayState;
|
2015-02-05 10:12:38 -08:00
|
|
|
struct Glop;
|
2014-06-23 13:13:08 -07:00
|
|
|
class RenderState;
|
2014-03-12 13:56:30 -07:00
|
|
|
class RenderNode;
|
2015-04-03 09:37:49 -07:00
|
|
|
class TextDrawFunctor;
|
2013-12-26 15:13:13 -08:00
|
|
|
class VertexBuffer;
|
|
|
|
|
2013-03-08 13:12:16 -08:00
|
|
|
enum StateDeferFlags {
|
|
|
|
kStateDeferFlag_Draw = 0x1,
|
|
|
|
kStateDeferFlag_Clip = 0x2
|
|
|
|
};
|
|
|
|
|
2013-05-31 11:38:03 -07:00
|
|
|
enum ClipSideFlags {
|
2013-06-14 13:43:58 -07:00
|
|
|
kClipSide_None = 0x0,
|
2013-05-31 11:38:03 -07:00
|
|
|
kClipSide_Left = 0x1,
|
|
|
|
kClipSide_Top = 0x2,
|
|
|
|
kClipSide_Right = 0x4,
|
|
|
|
kClipSide_Bottom = 0x8,
|
2013-06-17 13:52:06 -07:00
|
|
|
kClipSide_Full = 0xF,
|
|
|
|
kClipSide_ConservativeFull = 0x1F
|
2013-05-31 11:38:03 -07:00
|
|
|
};
|
|
|
|
|
2014-08-11 16:00:44 -07:00
|
|
|
enum VertexBufferDisplayFlags {
|
|
|
|
kVertexBuffer_Offset = 0x1,
|
2014-08-12 14:31:35 -07:00
|
|
|
kVertexBuffer_ShadowInterp = 0x2,
|
2014-08-11 16:00:44 -07:00
|
|
|
};
|
|
|
|
|
2013-11-15 16:06:56 -08:00
|
|
|
/**
|
|
|
|
* Defines additional transformation that should be applied by the model view matrix, beyond that of
|
|
|
|
* the currentTransform()
|
|
|
|
*/
|
|
|
|
enum ModelViewMode {
|
|
|
|
/**
|
|
|
|
* Used when the model view should simply translate geometry passed to the shader. The resulting
|
|
|
|
* matrix will be a simple translation.
|
|
|
|
*/
|
|
|
|
kModelViewMode_Translate = 0,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used when the model view should translate and scale geometry. The resulting matrix will be a
|
|
|
|
* translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
|
|
|
|
*/
|
|
|
|
kModelViewMode_TranslateAndScale = 1,
|
|
|
|
};
|
|
|
|
|
2010-06-23 17:47:49 -07:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Renderer
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2010-06-27 22:59:20 -07:00
|
|
|
/**
|
2013-12-30 15:32:54 -08:00
|
|
|
* OpenGL Renderer implementation.
|
2010-06-27 22:59:20 -07:00
|
|
|
*/
|
2015-02-25 11:01:09 -08:00
|
|
|
class OpenGLRenderer : public CanvasStateClient {
|
2010-06-16 18:44:05 -07:00
|
|
|
public:
|
2016-07-21 11:23:06 -07:00
|
|
|
explicit OpenGLRenderer(RenderState& renderState);
|
2010-09-24 18:39:22 -07:00
|
|
|
virtual ~OpenGLRenderer();
|
2010-06-16 18:44:05 -07:00
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
void initProperties();
|
2015-05-14 18:05:36 -07:00
|
|
|
void initLight(float lightRadius, uint8_t ambientShadowAlpha,
|
|
|
|
uint8_t spotShadowAlpha);
|
|
|
|
void setLightCenter(const Vector3& lightCenter);
|
2012-09-24 11:37:12 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
/*
|
|
|
|
* Prepares the renderer to draw a frame. This method must be invoked
|
|
|
|
* at the beginning of each frame. Only the specified rectangle of the
|
|
|
|
* frame is assumed to be dirty. A clip will automatically be set to
|
|
|
|
* the specified rectangle.
|
|
|
|
*
|
|
|
|
* @param opaque If true, the target surface is considered opaque
|
|
|
|
* and will not be cleared. If false, the target surface
|
|
|
|
* will be cleared
|
|
|
|
*/
|
2015-09-02 14:23:49 -07:00
|
|
|
virtual void prepareDirty(int viewportWidth, int viewportHeight,
|
|
|
|
float left, float top, float right, float bottom, bool opaque);
|
2012-08-08 14:53:48 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
/**
|
|
|
|
* Indicates the end of a frame. This method must be invoked whenever
|
|
|
|
* the caller is done rendering a frame.
|
|
|
|
* Returns true if any drawing was done during the frame (the output
|
|
|
|
* has changed / is "dirty" and should be displayed to the user).
|
|
|
|
*/
|
|
|
|
virtual bool finish();
|
|
|
|
|
|
|
|
void callDrawGLFunction(Functor* functor, Rect& dirty);
|
2010-06-21 19:35:50 -07:00
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
void pushLayerUpdate(Layer* layer);
|
|
|
|
void cancelLayerUpdate(Layer* layer);
|
|
|
|
void flushLayerUpdates();
|
2014-09-04 17:40:05 -07:00
|
|
|
void markLayersAsBuildLayers();
|
2012-09-21 00:39:43 -07:00
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
virtual int saveLayer(float left, float top, float right, float bottom,
|
2015-02-25 11:01:09 -08:00
|
|
|
const SkPaint* paint, int flags) {
|
2014-12-22 14:28:49 -08:00
|
|
|
return saveLayer(left, top, right, bottom, paint, flags, nullptr);
|
2014-04-15 16:18:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Specialized saveLayer implementation, which will pass the convexMask to an FBO layer, if
|
|
|
|
// created, which will in turn clip to that mask when drawn back/restored.
|
|
|
|
int saveLayer(float left, float top, float right, float bottom,
|
|
|
|
const SkPaint* paint, int flags, const SkPath* convexMask);
|
2010-06-26 00:13:53 -07:00
|
|
|
|
2013-03-19 15:03:48 -07:00
|
|
|
int saveLayerDeferred(float left, float top, float right, float bottom,
|
2014-02-05 16:47:00 -05:00
|
|
|
const SkPaint* paint, int flags);
|
2013-03-19 15:03:48 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
|
2015-08-20 12:41:40 -07:00
|
|
|
void drawLayer(Layer* layer);
|
2015-02-25 11:01:09 -08:00
|
|
|
void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
|
2014-01-02 17:13:34 -08:00
|
|
|
TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
|
2015-02-25 11:01:09 -08:00
|
|
|
void drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst,
|
|
|
|
const SkPaint* paint);
|
|
|
|
void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
|
|
|
|
const float* vertices, const int* colors, const SkPaint* paint);
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
|
2014-01-02 17:13:34 -08:00
|
|
|
TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
|
2014-01-02 17:13:34 -08:00
|
|
|
float left, float top, float right, float bottom, const SkPaint* paint);
|
2015-02-25 11:01:09 -08:00
|
|
|
void drawColor(int color, SkXfermode::Mode mode);
|
|
|
|
void drawRect(float left, float top, float right, float bottom,
|
|
|
|
const SkPaint* paint);
|
|
|
|
void drawRoundRect(float left, float top, float right, float bottom,
|
|
|
|
float rx, float ry, const SkPaint* paint);
|
|
|
|
void drawCircle(float x, float y, float radius, const SkPaint* paint);
|
|
|
|
void drawOval(float left, float top, float right, float bottom,
|
|
|
|
const SkPaint* paint);
|
|
|
|
void drawArc(float left, float top, float right, float bottom,
|
|
|
|
float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
|
|
|
|
void drawPath(const SkPath* path, const SkPaint* paint);
|
|
|
|
void drawLines(const float* points, int count, const SkPaint* paint);
|
|
|
|
void drawPoints(const float* points, int count, const SkPaint* paint);
|
2016-02-05 20:10:50 -08:00
|
|
|
void drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count, const SkPath* path,
|
2015-02-25 11:01:09 -08:00
|
|
|
float hOffset, float vOffset, const SkPaint* paint);
|
2016-02-05 20:10:50 -08:00
|
|
|
void drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y,
|
2014-01-02 17:13:34 -08:00
|
|
|
const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
|
2015-02-25 11:01:09 -08:00
|
|
|
DrawOpMode drawOpMode = DrawOpMode::kImmediate);
|
|
|
|
void drawRects(const float* rects, int count, const SkPaint* paint);
|
2010-06-22 13:11:24 -07:00
|
|
|
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawShadow(float casterAlpha,
|
2014-12-22 14:28:49 -08:00
|
|
|
const VertexBuffer* ambientShadowVertexBuffer,
|
|
|
|
const VertexBuffer* spotShadowVertexBuffer);
|
2013-10-25 18:30:17 -07:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
void setDrawFilter(SkDrawFilter* filter);
|
2012-01-23 17:09:05 -08:00
|
|
|
|
2013-07-30 19:05:20 -07:00
|
|
|
/**
|
|
|
|
* Store the current display state (most importantly, the current clip and transform), and
|
|
|
|
* additionally map the state's bounds from local to window coordinates.
|
|
|
|
*
|
|
|
|
* Returns true if quick-rejected
|
|
|
|
*/
|
2013-03-08 13:12:16 -08:00
|
|
|
bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
|
2013-03-04 10:19:31 -08:00
|
|
|
void restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore = false);
|
2013-05-31 11:38:03 -07:00
|
|
|
void setupMergedMultiDraw(const Rect* clipRect);
|
2013-02-04 16:16:33 -08:00
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
bool isCurrentTransformSimple() {
|
2014-01-01 14:45:21 -08:00
|
|
|
return currentTransform()->isSimple();
|
2013-01-04 19:05:13 -08:00
|
|
|
}
|
|
|
|
|
2013-03-01 14:31:04 -08:00
|
|
|
Caches& getCaches() {
|
|
|
|
return mCaches;
|
|
|
|
}
|
|
|
|
|
2015-01-26 18:06:29 -08:00
|
|
|
RenderState& renderState() {
|
|
|
|
return mRenderState;
|
|
|
|
}
|
|
|
|
|
2014-10-10 13:38:16 -04:00
|
|
|
int getViewportWidth() { return mState.getViewportWidth(); }
|
|
|
|
int getViewportHeight() { return mState.getViewportHeight(); }
|
2013-06-19 16:54:59 -07:00
|
|
|
|
2012-08-07 11:24:39 -07:00
|
|
|
/**
|
2013-03-15 17:24:33 -07:00
|
|
|
* Scales the alpha on the current snapshot. This alpha value will be modulated
|
2012-08-07 11:24:39 -07:00
|
|
|
* with other alpha values when drawing primitives.
|
|
|
|
*/
|
2014-10-10 13:38:16 -04:00
|
|
|
void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); }
|
2012-08-07 11:24:39 -07:00
|
|
|
|
2013-03-01 14:31:04 -08:00
|
|
|
/**
|
|
|
|
* Inserts a named event marker in the stream of GL commands.
|
|
|
|
*/
|
|
|
|
void eventMark(const char* name) const;
|
|
|
|
|
2014-07-29 10:35:13 -07:00
|
|
|
/**
|
|
|
|
* Inserts a formatted event marker in the stream of GL commands.
|
|
|
|
*/
|
|
|
|
void eventMarkDEBUG(const char *fmt, ...) const;
|
|
|
|
|
2012-08-07 11:24:39 -07:00
|
|
|
/**
|
|
|
|
* Inserts a named group marker in the stream of GL commands. This marker
|
|
|
|
* can be used by tools to group commands into logical groups. A call to
|
|
|
|
* this method must always be followed later on by a call to endMark().
|
|
|
|
*/
|
2012-01-30 17:41:55 -08:00
|
|
|
void startMark(const char* name) const;
|
2012-08-07 11:24:39 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Closes the last group marker opened by startMark().
|
|
|
|
*/
|
2012-01-30 17:41:55 -08:00
|
|
|
void endMark() const;
|
|
|
|
|
2013-03-05 16:43:31 -08:00
|
|
|
/**
|
2014-07-01 17:56:52 -07:00
|
|
|
* Build the best transform to use to rasterize text given a full
|
|
|
|
* transform matrix, and whether filteration is needed.
|
|
|
|
*
|
|
|
|
* Returns whether filtration is needed
|
2013-03-05 16:43:31 -08:00
|
|
|
*/
|
2014-07-01 17:56:52 -07:00
|
|
|
bool findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const;
|
2013-03-05 16:43:31 -08:00
|
|
|
|
2013-03-04 10:19:31 -08:00
|
|
|
#if DEBUG_MERGE_BEHAVIOR
|
|
|
|
void drawScreenSpaceColorRect(float left, float top, float right, float bottom, int color) {
|
|
|
|
mCaches.setScissorEnabled(false);
|
|
|
|
|
|
|
|
// should only be called outside of other draw ops, so stencil can only be in test state
|
|
|
|
bool stencilWasEnabled = mCaches.stencil.isTestEnabled();
|
|
|
|
mCaches.stencil.disable();
|
|
|
|
|
|
|
|
drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true);
|
|
|
|
|
|
|
|
if (stencilWasEnabled) mCaches.stencil.enableTest();
|
2014-09-08 11:26:26 -04:00
|
|
|
mDirty = true;
|
2013-03-04 10:19:31 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-10-10 13:38:16 -04:00
|
|
|
const Vector3& getLightCenter() const { return mState.currentLightCenter(); }
|
2014-06-02 16:27:04 -07:00
|
|
|
float getLightRadius() const { return mLightRadius; }
|
2014-08-14 13:34:01 -07:00
|
|
|
uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
|
|
|
|
uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
|
2014-06-02 16:27:04 -07:00
|
|
|
|
2014-10-10 13:38:16 -04:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
/// State manipulation
|
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
int getSaveCount() const;
|
|
|
|
int save(int flags);
|
|
|
|
void restore();
|
|
|
|
void restoreToCount(int saveCount);
|
2014-10-10 13:38:16 -04:00
|
|
|
|
2015-08-19 13:32:12 -07:00
|
|
|
void setGlobalMatrix(const Matrix4& matrix) {
|
|
|
|
mState.setMatrix(matrix);
|
|
|
|
}
|
|
|
|
void setLocalMatrix(const Matrix4& matrix);
|
2015-06-30 11:26:13 -04:00
|
|
|
void setLocalMatrix(const SkMatrix& matrix);
|
2015-02-25 11:01:09 -08:00
|
|
|
void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
|
2014-10-10 13:38:16 -04:00
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
void translate(float dx, float dy, float dz = 0.0f);
|
|
|
|
void rotate(float degrees);
|
|
|
|
void scale(float sx, float sy);
|
|
|
|
void skew(float sx, float sy);
|
2014-10-10 13:38:16 -04:00
|
|
|
|
|
|
|
void setMatrix(const Matrix4& matrix); // internal only convenience method
|
|
|
|
void concatMatrix(const Matrix4& matrix); // internal only convenience method
|
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); }
|
2014-10-10 13:38:16 -04:00
|
|
|
const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
|
2015-02-25 11:01:09 -08:00
|
|
|
bool quickRejectConservative(float left, float top,
|
|
|
|
float right, float bottom) const {
|
2014-10-10 13:38:16 -04:00
|
|
|
return mState.quickRejectConservative(left, top, right, bottom);
|
|
|
|
}
|
|
|
|
|
2015-02-25 11:01:09 -08:00
|
|
|
bool clipRect(float left, float top,
|
|
|
|
float right, float bottom, SkRegion::Op op);
|
|
|
|
bool clipPath(const SkPath* path, SkRegion::Op op);
|
|
|
|
bool clipRegion(const SkRegion* region, SkRegion::Op op);
|
2014-10-10 13:38:16 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Does not support different clipping Ops (that is, every call to setClippingOutline is
|
|
|
|
* effectively using SkRegion::kReplaceOp)
|
|
|
|
*
|
|
|
|
* The clipping outline is independent from the regular clip.
|
|
|
|
*/
|
|
|
|
void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
|
|
|
|
void setClippingRoundRect(LinearAllocator& allocator,
|
|
|
|
const Rect& rect, float radius, bool highPriority = true);
|
2015-04-28 11:45:59 -07:00
|
|
|
void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);
|
2014-10-10 13:38:16 -04:00
|
|
|
|
|
|
|
inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); }
|
|
|
|
inline const mat4* currentTransform() const { return mState.currentTransform(); }
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
/// CanvasStateClient interface
|
|
|
|
|
2014-12-22 14:28:49 -08:00
|
|
|
virtual void onViewportInitialized() override;
|
|
|
|
virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
|
2015-02-27 10:55:28 -08:00
|
|
|
virtual GLuint getTargetFbo() const override { return 0; }
|
2014-10-10 13:38:16 -04:00
|
|
|
|
2014-12-09 16:54:03 -08:00
|
|
|
SkPath* allocPathForFrame() {
|
2014-12-22 17:16:56 -08:00
|
|
|
std::unique_ptr<SkPath> path(new SkPath());
|
|
|
|
SkPath* returnPath = path.get();
|
|
|
|
mTempPaths.push_back(std::move(path));
|
|
|
|
return returnPath;
|
2014-12-09 16:54:03 -08:00
|
|
|
}
|
|
|
|
|
2015-06-30 11:26:13 -04:00
|
|
|
void setBaseTransform(const Matrix4& matrix) { mBaseTransform = matrix; }
|
|
|
|
|
2010-09-24 18:39:22 -07:00
|
|
|
protected:
|
2013-03-26 15:05:58 -07:00
|
|
|
/**
|
|
|
|
* Perform the setup specific to a frame. This method does not
|
|
|
|
* issue any OpenGL commands.
|
|
|
|
*/
|
2015-09-02 14:23:49 -07:00
|
|
|
void setupFrameState(int viewportWidth, int viewportHeight,
|
|
|
|
float left, float top, float right, float bottom, bool opaque);
|
2013-03-26 15:05:58 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates the start of rendering. This method will setup the
|
|
|
|
* initial OpenGL state (viewport, clearing the buffer, etc.)
|
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
void startFrame();
|
2013-03-26 15:05:58 -07:00
|
|
|
|
2012-10-18 15:05:02 -07:00
|
|
|
/**
|
|
|
|
* Clears the underlying surface if needed.
|
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
virtual void clear(float left, float top, float right, float bottom, bool opaque);
|
2012-10-18 15:05:02 -07:00
|
|
|
|
2012-09-18 15:40:58 -07:00
|
|
|
/**
|
|
|
|
* Call this method after updating a layer during a drawing pass.
|
|
|
|
*/
|
|
|
|
void resumeAfterLayer();
|
|
|
|
|
2013-01-15 18:51:42 -08:00
|
|
|
/**
|
|
|
|
* This method is called whenever a stencil buffer is required. Subclasses
|
|
|
|
* should override this method and call attachStencilBufferToLayer() on the
|
|
|
|
* appropriate layer(s).
|
|
|
|
*/
|
|
|
|
virtual void ensureStencilBuffer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Obtains a stencil render buffer (allocating it if necessary) and
|
|
|
|
* attaches it to the specified layer.
|
|
|
|
*/
|
|
|
|
void attachStencilBufferToLayer(Layer* layer);
|
|
|
|
|
2015-01-06 13:22:54 -08:00
|
|
|
/**
|
|
|
|
* Draw a rectangle list. Currently only used for the the stencil buffer so that the stencil
|
|
|
|
* will have a value of 'n' in every unclipped pixel, where 'n' is the number of rectangles
|
|
|
|
* in the list.
|
|
|
|
*/
|
|
|
|
void drawRectangleList(const RectangleList& rectangleList);
|
|
|
|
|
2013-11-19 18:00:46 -08:00
|
|
|
bool quickRejectSetupScissor(float left, float top, float right, float bottom,
|
2014-12-22 14:28:49 -08:00
|
|
|
const SkPaint* paint = nullptr);
|
|
|
|
bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = nullptr) {
|
2013-11-19 18:00:46 -08:00
|
|
|
return quickRejectSetupScissor(bounds.left, bounds.top,
|
|
|
|
bounds.right, bounds.bottom, paint);
|
|
|
|
}
|
|
|
|
|
2010-09-24 18:39:22 -07:00
|
|
|
/**
|
|
|
|
* Compose the layer defined in the current snapshot with the layer
|
|
|
|
* defined by the previous snapshot.
|
|
|
|
*
|
|
|
|
* The current snapshot *must* be a layer (flag kFlagIsLayer set.)
|
|
|
|
*
|
|
|
|
* @param curent The current snapshot containing the layer to compose
|
|
|
|
* @param previous The previous snapshot to compose the current layer with
|
|
|
|
*/
|
2013-12-30 15:32:54 -08:00
|
|
|
virtual void composeLayer(const Snapshot& current, const Snapshot& previous);
|
2010-07-21 21:33:20 -07:00
|
|
|
|
2011-01-13 12:13:20 -08:00
|
|
|
/**
|
2011-01-16 12:54:25 -08:00
|
|
|
* Marks the specified region as dirty at the specified bounds.
|
2011-01-13 12:13:20 -08:00
|
|
|
*/
|
2011-01-16 12:54:25 -08:00
|
|
|
void dirtyLayerUnchecked(Rect& bounds, Region* region);
|
2011-01-13 12:13:20 -08:00
|
|
|
|
2011-01-19 13:42:26 -08:00
|
|
|
/**
|
|
|
|
* Returns the region of the current layer.
|
|
|
|
*/
|
2013-03-05 16:43:31 -08:00
|
|
|
virtual Region* getRegion() const {
|
2014-10-10 13:38:16 -04:00
|
|
|
return mState.currentRegion();
|
2011-01-16 12:54:25 -08:00
|
|
|
}
|
|
|
|
|
2011-01-19 13:42:26 -08:00
|
|
|
/**
|
|
|
|
* Indicates whether rendering is currently targeted at a layer.
|
|
|
|
*/
|
2013-03-05 16:43:31 -08:00
|
|
|
virtual bool hasLayer() const {
|
2014-10-10 13:38:16 -04:00
|
|
|
return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion();
|
2011-01-16 12:54:25 -08:00
|
|
|
}
|
2011-01-14 20:07:20 -08:00
|
|
|
|
2011-06-14 16:45:55 -07:00
|
|
|
/**
|
|
|
|
* Renders the specified layer as a textured quad.
|
|
|
|
*
|
|
|
|
* @param layer The layer to render
|
|
|
|
* @param rect The bounds of the layer
|
|
|
|
*/
|
|
|
|
void drawTextureLayer(Layer* layer, const Rect& rect);
|
|
|
|
|
2013-03-29 10:59:59 -07:00
|
|
|
/**
|
2015-04-28 17:47:20 -07:00
|
|
|
* Gets the alpha from a layer, accounting for snapshot alpha
|
2013-03-29 10:59:59 -07:00
|
|
|
*
|
|
|
|
* @param layer The layer from which the alpha is extracted
|
|
|
|
*/
|
2013-12-10 12:28:58 -05:00
|
|
|
inline float getLayerAlpha(const Layer* layer) const;
|
2012-07-16 12:41:17 -07:00
|
|
|
|
2012-09-21 00:39:43 -07:00
|
|
|
/**
|
|
|
|
* Set to true to suppress error checks at the end of a frame.
|
|
|
|
*/
|
2013-03-05 16:43:31 -08:00
|
|
|
virtual bool suppressErrorChecks() const {
|
2012-09-21 00:39:43 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-10 13:38:16 -04:00
|
|
|
CanvasState mState;
|
2015-01-26 18:06:29 -08:00
|
|
|
Caches& mCaches;
|
|
|
|
RenderState& mRenderState;
|
2014-10-10 13:38:16 -04:00
|
|
|
|
2010-06-21 19:35:50 -07:00
|
|
|
private:
|
2015-06-23 17:33:06 -07:00
|
|
|
enum class GlopRenderType {
|
|
|
|
Standard,
|
|
|
|
Multi,
|
|
|
|
LayerClear
|
|
|
|
};
|
|
|
|
|
|
|
|
void renderGlop(const Glop& glop, GlopRenderType type = GlopRenderType::Standard);
|
2015-02-05 10:12:38 -08:00
|
|
|
|
2013-01-03 13:08:57 -08:00
|
|
|
/**
|
|
|
|
* Discards the content of the framebuffer if supported by the driver.
|
|
|
|
* This method should be called at the beginning of a frame to optimize
|
|
|
|
* rendering on some tiler architectures.
|
|
|
|
*/
|
|
|
|
void discardFramebuffer(float left, float top, float right, float bottom);
|
|
|
|
|
2010-06-27 22:59:20 -07:00
|
|
|
/**
|
|
|
|
* Sets the clipping rectangle using glScissor. The clip is defined by
|
|
|
|
* the current snapshot's clipRect member.
|
|
|
|
*/
|
2010-06-22 18:56:38 -07:00
|
|
|
void setScissorFromClip();
|
|
|
|
|
2013-01-15 18:51:42 -08:00
|
|
|
/**
|
|
|
|
* Sets the clipping region using the stencil buffer. The clip region
|
|
|
|
* is defined by the current snapshot's clipRegion member.
|
|
|
|
*/
|
|
|
|
void setStencilFromClip();
|
|
|
|
|
2013-03-19 15:03:48 -07:00
|
|
|
/**
|
2013-03-26 18:55:15 -07:00
|
|
|
* Given the local bounds of the layer, calculates ...
|
2013-03-19 15:03:48 -07:00
|
|
|
*/
|
|
|
|
void calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer);
|
|
|
|
|
2013-03-26 18:55:15 -07:00
|
|
|
/**
|
|
|
|
* Given the local bounds + clip of the layer, updates current snapshot's empty/invisible
|
|
|
|
*/
|
|
|
|
void updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect& clip,
|
|
|
|
bool fboLayer, int alpha);
|
|
|
|
|
2010-06-28 17:42:46 -07:00
|
|
|
/**
|
|
|
|
* Creates a new layer stored in the specified snapshot.
|
|
|
|
*
|
|
|
|
* @param snapshot The snapshot associated with the new layer
|
|
|
|
* @param left The left coordinate of the layer
|
|
|
|
* @param top The top coordinate of the layer
|
|
|
|
* @param right The right coordinate of the layer
|
|
|
|
* @param bottom The bottom coordinate of the layer
|
|
|
|
* @param alpha The translucency of the layer
|
|
|
|
* @param mode The blending mode of the layer
|
|
|
|
* @param flags The layer save flags
|
2014-04-15 16:18:08 -07:00
|
|
|
* @param mask A mask to use when drawing the layer back, may be empty
|
2010-06-28 17:42:46 -07:00
|
|
|
*
|
|
|
|
* @return True if the layer was successfully created, false otherwise
|
|
|
|
*/
|
2012-08-28 17:43:28 -07:00
|
|
|
bool createLayer(float left, float top, float right, float bottom,
|
2014-04-15 16:18:08 -07:00
|
|
|
const SkPaint* paint, int flags, const SkPath* convexMask);
|
2010-06-28 17:42:46 -07:00
|
|
|
|
2010-10-27 18:57:51 -07:00
|
|
|
/**
|
|
|
|
* Creates a new layer stored in the specified snapshot as an FBO.
|
|
|
|
*
|
|
|
|
* @param layer The layer to store as an FBO
|
|
|
|
* @param snapshot The snapshot associated with the new layer
|
|
|
|
* @param bounds The bounds of the layer
|
|
|
|
*/
|
2013-10-17 10:30:55 -07:00
|
|
|
bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip);
|
2010-10-27 18:57:51 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Compose the specified layer as a region.
|
|
|
|
*
|
|
|
|
* @param layer The layer to compose
|
|
|
|
* @param rect The layer's bounds
|
|
|
|
*/
|
|
|
|
void composeLayerRegion(Layer* layer, const Rect& rect);
|
|
|
|
|
|
|
|
/**
|
2015-06-01 10:35:35 -07:00
|
|
|
* Restores the content in layer to the screen, swapping the blend mode,
|
|
|
|
* specifically used in the restore() of a saveLayerAlpha().
|
2010-10-27 18:57:51 -07:00
|
|
|
*
|
2015-06-01 10:35:35 -07:00
|
|
|
* This allows e.g. a layer that would have been drawn on top of existing content (with SrcOver)
|
|
|
|
* to be drawn underneath.
|
|
|
|
*
|
|
|
|
* This will always ignore the canvas transform.
|
|
|
|
*/
|
|
|
|
void composeLayerRectSwapped(Layer* layer, const Rect& rect);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the content in layer to the screen.
|
2010-10-27 18:57:51 -07:00
|
|
|
*/
|
2015-06-01 10:35:35 -07:00
|
|
|
void composeLayerRect(Layer* layer, const Rect& rect);
|
2010-10-27 18:57:51 -07:00
|
|
|
|
2011-06-13 19:04:27 -07:00
|
|
|
/**
|
|
|
|
* Clears all the regions corresponding to the current list of layers.
|
|
|
|
* This method MUST be invoked before any drawing operation.
|
|
|
|
*/
|
|
|
|
void clearLayerRegions();
|
|
|
|
|
2011-01-16 12:54:25 -08:00
|
|
|
/**
|
|
|
|
* Mark the layer as dirty at the specified coordinates. The coordinates
|
|
|
|
* are transformed with the supplied matrix.
|
|
|
|
*/
|
|
|
|
void dirtyLayer(const float left, const float top,
|
2015-02-27 17:04:20 -08:00
|
|
|
const float right, const float bottom, const Matrix4& transform);
|
2011-01-16 12:54:25 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Mark the layer as dirty at the specified coordinates.
|
|
|
|
*/
|
|
|
|
void dirtyLayer(const float left, const float top,
|
|
|
|
const float right, const float bottom);
|
|
|
|
|
2010-06-27 22:59:20 -07:00
|
|
|
/**
|
|
|
|
* Draws a colored rectangle with the specified color. The specified coordinates
|
2012-12-03 12:34:51 -08:00
|
|
|
* are transformed by the current snapshot's transform matrix unless specified
|
|
|
|
* otherwise.
|
2010-06-27 22:59:20 -07:00
|
|
|
*
|
|
|
|
* @param left The left coordinate of the rectangle
|
|
|
|
* @param top The top coordinate of the rectangle
|
|
|
|
* @param right The right coordinate of the rectangle
|
|
|
|
* @param bottom The bottom coordinate of the rectangle
|
2013-12-10 12:28:58 -05:00
|
|
|
* @param paint The paint containing the color, blending mode, etc.
|
2010-07-14 16:34:53 -07:00
|
|
|
* @param ignoreTransform True if the current transform should be ignored
|
2010-06-27 22:59:20 -07:00
|
|
|
*/
|
2010-06-28 17:12:22 -07:00
|
|
|
void drawColorRect(float left, float top, float right, float bottom,
|
2013-12-10 12:28:58 -05:00
|
|
|
const SkPaint* paint, bool ignoreTransform = false);
|
2010-06-27 22:59:20 -07:00
|
|
|
|
2012-12-03 12:34:51 -08:00
|
|
|
/**
|
|
|
|
* Draws a series of colored rectangles with the specified color. The specified
|
|
|
|
* coordinates are transformed by the current snapshot's transform matrix unless
|
|
|
|
* specified otherwise.
|
|
|
|
*
|
|
|
|
* @param rects A list of rectangles, 4 floats (left, top, right, bottom)
|
|
|
|
* per rectangle
|
2013-12-10 12:28:58 -05:00
|
|
|
* @param paint The paint containing the color, blending mode, etc.
|
2012-12-03 12:34:51 -08:00
|
|
|
* @param ignoreTransform True if the current transform should be ignored
|
2013-01-15 18:51:42 -08:00
|
|
|
* @param dirty True if calling this method should dirty the current layer
|
2013-02-06 16:51:04 -08:00
|
|
|
* @param clip True if the rects should be clipped, false otherwise
|
2012-12-03 12:34:51 -08:00
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawColorRects(const float* rects, int count, const SkPaint* paint,
|
2013-12-10 12:28:58 -05:00
|
|
|
bool ignoreTransform = false, bool dirty = true, bool clip = true);
|
2012-12-03 12:34:51 -08:00
|
|
|
|
2011-06-13 19:04:27 -07:00
|
|
|
/**
|
|
|
|
* Draws the shape represented by the specified path texture.
|
|
|
|
* This method invokes drawPathTexture() but takes into account
|
|
|
|
* the extra left/top offset and the texture offset to correctly
|
|
|
|
* position the final shape.
|
|
|
|
*
|
|
|
|
* @param left The left coordinate of the shape to render
|
|
|
|
* @param top The top coordinate of the shape to render
|
|
|
|
* @param texture The texture reprsenting the shape
|
|
|
|
* @param paint The paint to draw the shape with
|
|
|
|
*/
|
2015-02-12 10:41:39 -08:00
|
|
|
void drawShape(float left, float top, PathTexture* texture, const SkPaint* paint);
|
2011-06-13 19:04:27 -07:00
|
|
|
|
2012-12-10 17:56:27 -08:00
|
|
|
/**
|
|
|
|
* Renders a strip of polygons with the specified paint, used for tessellated geometry.
|
|
|
|
*
|
|
|
|
* @param vertexBuffer The VertexBuffer to be drawn
|
|
|
|
* @param paint The paint to render with
|
2014-08-11 16:00:44 -07:00
|
|
|
* @param flags flags with which to draw
|
2012-12-10 17:56:27 -08:00
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
|
2014-08-11 16:00:44 -07:00
|
|
|
const SkPaint* paint, int flags = 0);
|
2012-12-10 17:56:27 -08:00
|
|
|
|
2014-06-02 16:27:04 -07:00
|
|
|
/**
|
|
|
|
* Convenience for translating method
|
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawVertexBuffer(const VertexBuffer& vertexBuffer,
|
2014-08-11 16:00:44 -07:00
|
|
|
const SkPaint* paint, int flags = 0) {
|
2014-09-08 11:26:26 -04:00
|
|
|
drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
|
2014-06-02 16:27:04 -07:00
|
|
|
}
|
|
|
|
|
2011-06-13 19:04:27 -07:00
|
|
|
/**
|
2012-09-17 17:25:49 -07:00
|
|
|
* Renders the convex hull defined by the specified path as a strip of polygons.
|
2011-06-13 19:04:27 -07:00
|
|
|
*
|
2012-09-17 17:25:49 -07:00
|
|
|
* @param path The hull of the path to draw
|
2012-09-25 12:00:29 -07:00
|
|
|
* @param paint The paint to render with
|
2011-06-13 19:04:27 -07:00
|
|
|
*/
|
2014-09-08 11:26:26 -04:00
|
|
|
void drawConvexPath(const SkPath& path, const SkPaint* paint);
|
2011-05-12 09:06:00 -07:00
|
|
|
|
2012-07-19 22:48:17 -07:00
|
|
|
/**
|
|
|
|
* Draws shadow layer on text (with optional positions).
|
|
|
|
*
|
|
|
|
* @param paint The paint to draw the shadow with
|
|
|
|
* @param text The text to draw
|
|
|
|
* @param count The number of glyphs in the text
|
|
|
|
* @param positions The x, y positions of individual glyphs (or NULL)
|
|
|
|
* @param fontRenderer The font renderer object
|
|
|
|
* @param alpha The alpha value for drawing the shadow
|
|
|
|
* @param x The x coordinate where the shadow will be drawn
|
|
|
|
* @param y The y coordinate where the shadow will be drawn
|
|
|
|
*/
|
2016-02-05 20:10:50 -08:00
|
|
|
void drawTextShadow(const SkPaint* paint, const glyph_t* glyphs, int count,
|
2013-12-10 12:28:58 -05:00
|
|
|
const float* positions, FontRenderer& fontRenderer, int alpha,
|
2012-07-19 22:48:17 -07:00
|
|
|
float x, float y);
|
|
|
|
|
2011-06-13 19:04:27 -07:00
|
|
|
/**
|
|
|
|
* Draws a path texture. Path textures are alpha8 bitmaps that need special
|
|
|
|
* compositing to apply colors/filters/etc.
|
|
|
|
*
|
|
|
|
* @param texture The texture to render
|
|
|
|
* @param x The x coordinate where the texture will be drawn
|
|
|
|
* @param y The y coordinate where the texture will be drawn
|
|
|
|
* @param paint The paint to draw the texture with
|
|
|
|
*/
|
2015-02-12 10:41:39 -08:00
|
|
|
void drawPathTexture(PathTexture* texture, float x, float y, const SkPaint* paint);
|
2011-01-19 21:54:02 -08:00
|
|
|
|
2010-06-28 17:12:22 -07:00
|
|
|
/**
|
2010-07-27 17:39:27 -07:00
|
|
|
* Resets the texture coordinates stored in mMeshVertices. Setting the values
|
2010-06-28 17:12:22 -07:00
|
|
|
* back to default is achieved by calling:
|
|
|
|
*
|
2010-06-30 19:21:21 -07:00
|
|
|
* resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
|
2010-06-28 17:12:22 -07:00
|
|
|
*
|
|
|
|
* @param u1 The left coordinate of the texture
|
|
|
|
* @param v1 The bottom coordinate of the texture
|
|
|
|
* @param u2 The right coordinate of the texture
|
|
|
|
* @param v2 The top coordinate of the texture
|
|
|
|
*/
|
|
|
|
void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2);
|
|
|
|
|
2013-02-27 13:50:45 -08:00
|
|
|
/**
|
|
|
|
* Returns true if the specified paint will draw invisible text.
|
|
|
|
*/
|
|
|
|
bool canSkipText(const SkPaint* paint) const;
|
|
|
|
|
2012-09-21 00:39:43 -07:00
|
|
|
bool updateLayer(Layer* layer, bool inFrame);
|
|
|
|
void updateLayers();
|
2013-03-26 15:05:58 -07:00
|
|
|
void flushLayers();
|
2012-09-21 00:39:43 -07:00
|
|
|
|
2013-10-17 10:30:55 -07:00
|
|
|
#if DEBUG_LAYERS_AS_REGIONS
|
2012-08-07 11:24:39 -07:00
|
|
|
/**
|
|
|
|
* Renders the specified region as a series of rectangles. This method
|
|
|
|
* is used for debugging only.
|
|
|
|
*/
|
2013-10-17 10:30:55 -07:00
|
|
|
void drawRegionRectsDebug(const Region& region);
|
|
|
|
#endif
|
2011-02-01 22:59:58 -08:00
|
|
|
|
2013-01-15 18:51:42 -08:00
|
|
|
/**
|
|
|
|
* Renders the specified region as a series of rectangles. The region
|
|
|
|
* must be in screen-space coordinates.
|
|
|
|
*/
|
2013-12-10 12:28:58 -05:00
|
|
|
void drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty = false);
|
2013-01-15 18:51:42 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
|
|
|
|
* is turned on.
|
|
|
|
*/
|
|
|
|
void debugClip();
|
|
|
|
|
2012-09-21 19:15:00 -07:00
|
|
|
void debugOverdraw(bool enable, bool clear);
|
|
|
|
void renderOverdraw();
|
2013-05-03 14:24:16 -07:00
|
|
|
void countOverdraw();
|
2012-09-21 19:15:00 -07:00
|
|
|
|
2010-10-26 16:27:31 -07:00
|
|
|
/**
|
|
|
|
* Should be invoked every time the glScissor is modified.
|
|
|
|
*/
|
2014-10-10 13:38:16 -04:00
|
|
|
inline void dirtyClip() { mState.setDirtyClip(true); }
|
2010-10-26 16:27:31 -07:00
|
|
|
|
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
in the GL shaders.
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
2013-04-17 18:54:38 -07:00
|
|
|
inline const UvMapper& getMapper(const Texture* texture) {
|
|
|
|
return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a texture object for the specified bitmap. The texture can
|
|
|
|
* come from the texture cache or an atlas. If this method returns
|
|
|
|
* NULL, the texture could not be found and/or allocated.
|
|
|
|
*/
|
2014-01-02 17:13:34 -08:00
|
|
|
Texture* getTexture(const SkBitmap* bitmap);
|
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
in the GL shaders.
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
2013-04-17 18:54:38 -07:00
|
|
|
|
2014-09-08 11:26:26 -04:00
|
|
|
bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; }
|
2014-10-10 13:38:16 -04:00
|
|
|
inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); }
|
|
|
|
inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); }
|
2014-09-08 11:26:26 -04:00
|
|
|
|
2012-09-19 17:25:38 -07:00
|
|
|
// State used to define the clipping region
|
2013-03-21 14:39:04 -07:00
|
|
|
Rect mTilingClip;
|
2013-03-26 15:05:58 -07:00
|
|
|
// Is the target render surface opaque
|
|
|
|
bool mOpaque;
|
|
|
|
// Is a frame currently being rendered
|
|
|
|
bool mFrameStarted;
|
2010-06-24 19:30:36 -07:00
|
|
|
|
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
in the GL shaders.
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
2013-04-17 18:54:38 -07:00
|
|
|
// Default UV mapper
|
|
|
|
const UvMapper mUvMapper;
|
|
|
|
|
2012-03-27 16:33:45 -07:00
|
|
|
// List of rectangles to clear after saveLayer() is invoked
|
2014-12-22 17:16:56 -08:00
|
|
|
std::vector<Rect> mLayers;
|
2012-09-21 00:39:43 -07:00
|
|
|
// List of layers to update at the beginning of a frame
|
2015-07-29 16:48:58 -07:00
|
|
|
std::vector< sp<Layer> > mLayerUpdates;
|
2011-06-13 19:04:27 -07:00
|
|
|
|
2012-09-24 11:37:12 -07:00
|
|
|
// See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
|
|
|
|
// Properties.h
|
|
|
|
bool mScissorOptimizationDisabled;
|
|
|
|
|
2014-05-05 19:09:33 -07:00
|
|
|
bool mSkipOutlineClip;
|
|
|
|
|
2014-09-08 11:26:26 -04:00
|
|
|
// True if anything has been drawn since the last call to
|
|
|
|
// reportAndClearDirty()
|
|
|
|
bool mDirty;
|
|
|
|
|
2014-07-23 18:19:28 -07:00
|
|
|
// Lighting + shadows
|
|
|
|
Vector3 mLightCenter;
|
|
|
|
float mLightRadius;
|
|
|
|
uint8_t mAmbientShadowAlpha;
|
|
|
|
uint8_t mSpotShadowAlpha;
|
|
|
|
|
2014-12-09 16:54:03 -08:00
|
|
|
// Paths kept alive for the duration of the frame
|
2014-12-22 17:16:56 -08:00
|
|
|
std::vector<std::unique_ptr<SkPath>> mTempPaths;
|
2014-12-09 16:54:03 -08:00
|
|
|
|
2015-06-30 11:26:13 -04:00
|
|
|
/**
|
|
|
|
* Initial transform for a rendering pass; transform from global device
|
|
|
|
* coordinates to the current RenderNode's drawing content coordinates,
|
|
|
|
* with the RenderNode's RenderProperty transforms already applied.
|
|
|
|
* Calling setMatrix(mBaseTransform) will result in drawing at the origin
|
|
|
|
* of the DisplayList's recorded surface prior to any Canvas
|
|
|
|
* transformation.
|
|
|
|
*/
|
|
|
|
Matrix4 mBaseTransform;
|
|
|
|
|
2013-03-26 15:05:58 -07:00
|
|
|
friend class Layer;
|
2015-04-03 09:37:49 -07:00
|
|
|
friend class TextDrawFunctor;
|
2013-06-20 18:30:28 -07:00
|
|
|
friend class DrawBitmapOp;
|
|
|
|
friend class DrawPatchOp;
|
2010-09-28 19:09:36 -07:00
|
|
|
|
2010-06-22 18:56:38 -07:00
|
|
|
}; // class OpenGLRenderer
|
2010-06-16 18:44:05 -07:00
|
|
|
|
2010-06-24 19:30:36 -07:00
|
|
|
}; // namespace uirenderer
|
2010-06-16 18:44:05 -07:00
|
|
|
}; // namespace android
|
|
|
|
|
2010-10-27 18:57:51 -07:00
|
|
|
#endif // ANDROID_HWUI_OPENGL_RENDERER_H
|