2010-09-26 18:40:37 -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_DISPLAY_LIST_RENDERER_H
|
|
|
|
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
2010-09-26 18:40:37 -07:00
|
|
|
|
|
|
|
#include <SkChunkAlloc.h>
|
|
|
|
#include <SkFlattenable.h>
|
|
|
|
#include <SkMatrix.h>
|
|
|
|
#include <SkPaint.h>
|
|
|
|
#include <SkPath.h>
|
|
|
|
#include <SkPictureFlat.h>
|
|
|
|
#include <SkRefCnt.h>
|
|
|
|
#include <SkTDArray.h>
|
|
|
|
#include <SkTSearch.h>
|
|
|
|
|
|
|
|
#include "OpenGLRenderer.h"
|
|
|
|
|
|
|
|
namespace android {
|
|
|
|
namespace uirenderer {
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Defines
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#define MIN_WRITER_SIZE 16384
|
|
|
|
#define HEAP_BLOCK_SIZE 4096
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Helpers
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class PathHeap: public SkRefCnt {
|
|
|
|
public:
|
2010-10-01 16:36:14 -07:00
|
|
|
PathHeap();
|
|
|
|
PathHeap(SkFlattenableReadBuffer& buffer);
|
|
|
|
~PathHeap();
|
2010-09-26 18:40:37 -07:00
|
|
|
|
2010-10-01 16:36:14 -07:00
|
|
|
int append(const SkPath& path);
|
2010-09-26 18:40:37 -07:00
|
|
|
|
|
|
|
int count() const { return mPaths.count(); }
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
SkPath& operator[](int index) const {
|
2010-09-26 18:40:37 -07:00
|
|
|
return *mPaths[index];
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:36:14 -07:00
|
|
|
void flatten(SkFlattenableWriteBuffer& buffer) const;
|
2010-09-26 18:40:37 -07:00
|
|
|
|
|
|
|
private:
|
|
|
|
SkChunkAlloc mHeap;
|
|
|
|
SkTDArray<SkPath*> mPaths;
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2010-09-28 19:09:36 -07:00
|
|
|
// Display list
|
2010-09-26 18:40:37 -07:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
class DisplayListRenderer;
|
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
/**
|
2010-09-28 19:09:36 -07:00
|
|
|
* Replays recorded drawing commands.
|
2010-09-26 18:40:37 -07:00
|
|
|
*/
|
2010-09-28 19:09:36 -07:00
|
|
|
class DisplayList {
|
2010-09-26 18:40:37 -07:00
|
|
|
public:
|
2010-09-28 19:09:36 -07:00
|
|
|
DisplayList(const DisplayListRenderer& recorder);
|
|
|
|
~DisplayList();
|
2010-09-26 18:40:37 -07:00
|
|
|
|
|
|
|
enum Op {
|
|
|
|
AcquireContext,
|
|
|
|
ReleaseContext,
|
|
|
|
Save,
|
|
|
|
Restore,
|
|
|
|
RestoreToCount,
|
|
|
|
SaveLayer,
|
2010-10-27 18:57:51 -07:00
|
|
|
SaveLayerAlpha,
|
2010-09-26 18:40:37 -07:00
|
|
|
Translate,
|
|
|
|
Rotate,
|
|
|
|
Scale,
|
|
|
|
SetMatrix,
|
|
|
|
ConcatMatrix,
|
|
|
|
ClipRect,
|
2010-11-08 12:08:41 -08:00
|
|
|
DrawDisplayList,
|
2010-09-26 18:40:37 -07:00
|
|
|
DrawBitmap,
|
|
|
|
DrawBitmapMatrix,
|
|
|
|
DrawBitmapRect,
|
|
|
|
DrawPatch,
|
|
|
|
DrawColor,
|
|
|
|
DrawRect,
|
|
|
|
DrawPath,
|
|
|
|
DrawLines,
|
|
|
|
DrawText,
|
|
|
|
ResetShader,
|
|
|
|
SetupShader,
|
|
|
|
ResetColorFilter,
|
|
|
|
SetupColorFilter,
|
|
|
|
ResetShadow,
|
|
|
|
SetupShadow
|
|
|
|
};
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
void replay(OpenGLRenderer& renderer);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void init();
|
|
|
|
|
|
|
|
class TextContainer {
|
|
|
|
public:
|
|
|
|
size_t length() const {
|
|
|
|
return mByteLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* text() const {
|
|
|
|
return (const char*) mText;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t mByteLength;
|
|
|
|
const char* mText;
|
|
|
|
};
|
|
|
|
|
|
|
|
SkBitmap* getBitmap() {
|
2010-10-08 08:37:55 -07:00
|
|
|
return (SkBitmap*) getInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
SkiaShader* getShader() {
|
|
|
|
return (SkiaShader*) getInt();
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
2010-10-22 16:17:12 -07:00
|
|
|
SkiaColorFilter* getColorFilter() {
|
|
|
|
return (SkiaColorFilter*) getInt();
|
|
|
|
}
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
inline int getIndex() {
|
|
|
|
return mReader.readInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int getInt() {
|
|
|
|
return mReader.readInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
SkMatrix* getMatrix() {
|
2010-10-08 08:37:55 -07:00
|
|
|
return (SkMatrix*) getInt();
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
SkPath* getPath() {
|
|
|
|
return &(*mPathHeap)[getInt() - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
SkPaint* getPaint() {
|
2010-10-08 08:37:55 -07:00
|
|
|
return (SkPaint*) getInt();
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
2010-11-08 12:08:41 -08:00
|
|
|
DisplayList* getDisplayList() {
|
|
|
|
return (DisplayList*) getInt();
|
|
|
|
}
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
inline float getFloat() {
|
|
|
|
return mReader.readScalar();
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t* getInts(uint32_t& count) {
|
|
|
|
count = getInt();
|
|
|
|
return (int32_t*) mReader.skip(count * sizeof(int32_t));
|
|
|
|
}
|
|
|
|
|
2010-10-12 15:59:26 -07:00
|
|
|
uint32_t* getUInts(int8_t& count) {
|
|
|
|
count = getInt();
|
|
|
|
return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
|
|
|
|
}
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
float* getFloats(int& count) {
|
|
|
|
count = getInt();
|
|
|
|
return (float*) mReader.skip(count * sizeof(float));
|
|
|
|
}
|
|
|
|
|
|
|
|
void getText(TextContainer* text) {
|
|
|
|
size_t length = text->mByteLength = getInt();
|
|
|
|
text->mText = (const char*) mReader.skip(length);
|
|
|
|
}
|
|
|
|
|
|
|
|
PathHeap* mPathHeap;
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
Vector<SkBitmap*> mBitmapResources;
|
|
|
|
Vector<SkiaShader*> mShaderResources;
|
2010-10-22 16:17:12 -07:00
|
|
|
Vector<SkiaColorFilter*> mFilterResources;
|
2010-09-28 19:09:36 -07:00
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
Vector<SkPaint*> mPaints;
|
|
|
|
Vector<SkMatrix*> mMatrices;
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
mutable SkFlattenableReadBuffer mReader;
|
|
|
|
|
|
|
|
SkRefCntPlayback mRCPlayback;
|
|
|
|
SkTypefacePlayback mTFPlayback;
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Renderer
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Records drawing commands in a display list for latter playback.
|
|
|
|
*/
|
|
|
|
class DisplayListRenderer: public OpenGLRenderer {
|
|
|
|
public:
|
|
|
|
DisplayListRenderer();
|
|
|
|
~DisplayListRenderer();
|
|
|
|
|
|
|
|
void setViewport(int width, int height);
|
2010-10-06 19:49:23 -07:00
|
|
|
void prepare(bool opaque);
|
2010-09-28 19:09:36 -07:00
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
void acquireContext();
|
|
|
|
void releaseContext();
|
|
|
|
|
|
|
|
int save(int flags);
|
|
|
|
void restore();
|
|
|
|
void restoreToCount(int saveCount);
|
|
|
|
|
|
|
|
int saveLayer(float left, float top, float right, float bottom,
|
2010-10-08 08:37:55 -07:00
|
|
|
SkPaint* p, int flags);
|
2010-10-27 18:57:51 -07:00
|
|
|
int saveLayerAlpha(float left, float top, float right, float bottom,
|
|
|
|
int alpha, int flags);
|
2010-09-26 18:40:37 -07:00
|
|
|
|
|
|
|
void translate(float dx, float dy);
|
|
|
|
void rotate(float degrees);
|
|
|
|
void scale(float sx, float sy);
|
|
|
|
|
|
|
|
void setMatrix(SkMatrix* matrix);
|
|
|
|
void concatMatrix(SkMatrix* matrix);
|
|
|
|
|
|
|
|
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
|
|
|
|
2010-11-08 12:08:41 -08:00
|
|
|
void drawDisplayList(DisplayList* displayList);
|
2010-10-08 08:37:55 -07:00
|
|
|
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
|
|
|
|
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
|
2010-09-26 18:40:37 -07:00
|
|
|
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
|
|
|
|
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
2010-10-08 08:37:55 -07:00
|
|
|
float dstRight, float dstBottom, SkPaint* paint);
|
2010-09-26 18:40:37 -07:00
|
|
|
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
2010-10-12 15:59:26 -07:00
|
|
|
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
2010-10-08 08:37:55 -07:00
|
|
|
float left, float top, float right, float bottom, SkPaint* paint);
|
2010-09-26 18:40:37 -07:00
|
|
|
void drawColor(int color, SkXfermode::Mode mode);
|
2010-10-08 08:37:55 -07:00
|
|
|
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
2010-09-26 18:40:37 -07:00
|
|
|
void drawPath(SkPath* path, SkPaint* paint);
|
2010-10-08 08:37:55 -07:00
|
|
|
void drawLines(float* points, int count, SkPaint* paint);
|
2010-09-26 18:40:37 -07:00
|
|
|
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
|
|
|
|
|
|
|
|
void resetShader();
|
|
|
|
void setupShader(SkiaShader* shader);
|
|
|
|
|
|
|
|
void resetColorFilter();
|
|
|
|
void setupColorFilter(SkiaColorFilter* filter);
|
|
|
|
|
|
|
|
void resetShadow();
|
|
|
|
void setupShadow(float radius, float dx, float dy, int color);
|
|
|
|
|
|
|
|
void reset();
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
DisplayList* getDisplayList() const {
|
|
|
|
return new DisplayList(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
const SkWriter32& writeStream() const {
|
|
|
|
return mWriter;
|
|
|
|
}
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
const Vector<SkBitmap*>& getBitmapResources() const {
|
|
|
|
return mBitmapResources;
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
const Vector<SkiaShader*>& getShaderResources() const {
|
|
|
|
return mShaderResources;
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
const Vector<SkPaint*>& getPaints() const {
|
|
|
|
return mPaints;
|
2010-10-08 08:37:55 -07:00
|
|
|
}
|
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
const Vector<SkMatrix*>& getMatrices() const {
|
|
|
|
return mMatrices;
|
2010-09-28 19:09:36 -07:00
|
|
|
}
|
|
|
|
|
2010-10-22 16:17:12 -07:00
|
|
|
const Vector<SkiaColorFilter*>& getFilterResources() const {
|
|
|
|
return mFilterResources;
|
|
|
|
}
|
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
private:
|
2010-09-28 19:09:36 -07:00
|
|
|
inline void addOp(DisplayList::Op drawOp) {
|
2010-09-26 18:40:37 -07:00
|
|
|
mWriter.writeInt(drawOp);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addInt(int value) {
|
|
|
|
mWriter.writeInt(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void addInts(const int32_t* values, uint32_t count) {
|
2010-09-28 19:09:36 -07:00
|
|
|
mWriter.writeInt(count);
|
2010-09-26 18:40:37 -07:00
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
2010-10-12 15:59:26 -07:00
|
|
|
mWriter.writeInt(values[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void addUInts(const uint32_t* values, int8_t count) {
|
|
|
|
mWriter.writeInt(count);
|
|
|
|
for (int8_t i = 0; i < count; i++) {
|
2010-09-26 18:40:37 -07:00
|
|
|
mWriter.writeInt(values[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addFloat(float value) {
|
|
|
|
mWriter.writeScalar(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void addFloats(const float* values, int count) {
|
2010-09-28 19:09:36 -07:00
|
|
|
mWriter.writeInt(count);
|
2010-09-26 18:40:37 -07:00
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
mWriter.writeScalar(values[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addPoint(float x, float y) {
|
|
|
|
mWriter.writeScalar(x);
|
|
|
|
mWriter.writeScalar(y);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addBounds(float left, float top, float right, float bottom) {
|
|
|
|
mWriter.writeScalar(left);
|
|
|
|
mWriter.writeScalar(top);
|
|
|
|
mWriter.writeScalar(right);
|
|
|
|
mWriter.writeScalar(bottom);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addText(const void* text, size_t byteLength) {
|
|
|
|
mWriter.writeInt(byteLength);
|
|
|
|
mWriter.writePad(text, byteLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addPath(const SkPath* path) {
|
|
|
|
if (mPathHeap == NULL) {
|
|
|
|
mPathHeap = new PathHeap();
|
|
|
|
}
|
|
|
|
addInt(mPathHeap->append(*path));
|
|
|
|
}
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
inline void addPaint(SkPaint* paint) {
|
2010-10-25 15:47:32 -07:00
|
|
|
if (paint == NULL) {
|
2010-11-08 12:08:41 -08:00
|
|
|
addInt((int) NULL);
|
2010-10-25 15:47:32 -07:00
|
|
|
return;
|
|
|
|
}
|
2010-11-08 12:08:41 -08:00
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
SkPaint *paintCopy = mPaintMap.valueFor(paint);
|
|
|
|
if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
|
|
|
|
paintCopy = new SkPaint(*paint);
|
|
|
|
mPaintMap.add(paint, paintCopy);
|
|
|
|
mPaints.add(paintCopy);
|
|
|
|
}
|
2010-11-08 12:08:41 -08:00
|
|
|
|
|
|
|
addInt((int) paintCopy);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void addDisplayList(DisplayList* displayList) {
|
|
|
|
// TODO: To be safe, the display list should be ref-counted in the
|
|
|
|
// resources cache, but we rely on the caller (UI toolkit) to
|
|
|
|
// do the right thing for now
|
|
|
|
addInt((int) displayList);
|
2010-09-26 18:40:37 -07:00
|
|
|
}
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
inline void addMatrix(SkMatrix* matrix) {
|
2010-10-25 15:47:32 -07:00
|
|
|
// Copying the matrix is cheap and prevents against the user changing the original
|
|
|
|
// matrix before the operation that uses it
|
|
|
|
addInt((int) new SkMatrix(*matrix));
|
2010-09-26 18:40:37 -07:00
|
|
|
}
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
inline void addBitmap(SkBitmap* bitmap) {
|
2010-10-25 15:47:32 -07:00
|
|
|
// Note that this assumes the bitmap is immutable. There are cases this won't handle
|
|
|
|
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
|
|
|
|
// contents, and drawing again. The only fix would be to always copy it the first time,
|
|
|
|
// which doesn't seem worth the extra cycles for this unlikely case.
|
2010-11-08 12:08:41 -08:00
|
|
|
addInt((int) bitmap);
|
2010-10-08 08:37:55 -07:00
|
|
|
mBitmapResources.add(bitmap);
|
|
|
|
Caches& caches = Caches::getInstance();
|
|
|
|
caches.resourceCache.incrementRefcount(bitmap);
|
|
|
|
}
|
2010-09-26 18:40:37 -07:00
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
inline void addShader(SkiaShader* shader) {
|
2010-11-08 12:08:41 -08:00
|
|
|
addInt((int) shader);
|
2010-10-08 08:37:55 -07:00
|
|
|
mShaderResources.add(shader);
|
|
|
|
Caches& caches = Caches::getInstance();
|
|
|
|
caches.resourceCache.incrementRefcount(shader);
|
2010-09-26 18:40:37 -07:00
|
|
|
}
|
|
|
|
|
2010-10-22 16:17:12 -07:00
|
|
|
inline void addColorFilter(SkiaColorFilter* colorFilter) {
|
2010-11-08 12:08:41 -08:00
|
|
|
addInt((int) colorFilter);
|
2010-10-22 16:17:12 -07:00
|
|
|
mFilterResources.add(colorFilter);
|
|
|
|
Caches& caches = Caches::getInstance();
|
|
|
|
caches.resourceCache.incrementRefcount(colorFilter);
|
|
|
|
}
|
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
SkChunkAlloc mHeap;
|
|
|
|
|
2010-10-08 08:37:55 -07:00
|
|
|
Vector<SkBitmap*> mBitmapResources;
|
|
|
|
Vector<SkiaShader*> mShaderResources;
|
2010-10-22 16:17:12 -07:00
|
|
|
Vector<SkiaColorFilter*> mFilterResources;
|
2010-09-26 18:40:37 -07:00
|
|
|
|
2010-10-25 15:47:32 -07:00
|
|
|
Vector<SkPaint*> mPaints;
|
2010-11-08 12:08:41 -08:00
|
|
|
DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
|
2010-10-25 15:47:32 -07:00
|
|
|
Vector<SkMatrix*> mMatrices;
|
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
PathHeap* mPathHeap;
|
|
|
|
SkWriter32 mWriter;
|
|
|
|
|
|
|
|
SkRefCntRecorder mRCRecorder;
|
|
|
|
SkRefCntRecorder mTFRecorder;
|
|
|
|
|
2010-09-28 19:09:36 -07:00
|
|
|
friend class DisplayList;
|
|
|
|
|
2010-09-26 18:40:37 -07:00
|
|
|
}; // class DisplayListRenderer
|
|
|
|
|
|
|
|
}; // namespace uirenderer
|
|
|
|
}; // namespace android
|
|
|
|
|
2010-10-27 18:57:51 -07:00
|
|
|
#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|