Merge "Add support for partial invalidates in WebView Bug #3461349" into honeycomb-mr1
This commit is contained in:
@@ -245,11 +245,12 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
private static native void nDestroyDisplayList(int displayList);
|
||||
|
||||
@Override
|
||||
public boolean drawDisplayList(DisplayList displayList) {
|
||||
return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
|
||||
public boolean drawDisplayList(DisplayList displayList, Rect dirty) {
|
||||
return nDrawDisplayList(mRenderer,
|
||||
((GLES20DisplayList) displayList).mNativeDisplayList, dirty);
|
||||
}
|
||||
|
||||
private static native boolean nDrawDisplayList(int renderer, int displayList);
|
||||
private static native boolean nDrawDisplayList(int renderer, int displayList, Rect dirty);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Hardware layer
|
||||
|
||||
@@ -53,8 +53,13 @@ public abstract class HardwareCanvas extends Canvas {
|
||||
* Draws the specified display list onto this canvas.
|
||||
*
|
||||
* @param displayList The display list to replay.
|
||||
* @param dirty The dirty region to redraw in the next pass, matters only
|
||||
* if this method returns true, can be null.
|
||||
*
|
||||
* @return True if the content of the display list requires another
|
||||
* drawing pass (invalidate()), false otherwise
|
||||
*/
|
||||
abstract boolean drawDisplayList(DisplayList displayList);
|
||||
abstract boolean drawDisplayList(DisplayList displayList, Rect dirty);
|
||||
|
||||
/**
|
||||
* Draws the specified layer onto this canvas.
|
||||
|
||||
@@ -269,7 +269,7 @@ public abstract class HardwareRenderer {
|
||||
static EGLDisplay sEglDisplay;
|
||||
static EGLConfig sEglConfig;
|
||||
|
||||
private static Thread sEglThread;
|
||||
private static Thread sEglThread;
|
||||
|
||||
EGLSurface mEglSurface;
|
||||
|
||||
@@ -284,6 +284,8 @@ public abstract class HardwareRenderer {
|
||||
final boolean mTranslucent;
|
||||
|
||||
private boolean mDestroyed;
|
||||
|
||||
private final Rect mRedrawClip = new Rect();
|
||||
|
||||
GlRenderer(int glVersion, boolean translucent) {
|
||||
mGlVersion = glVersion;
|
||||
@@ -606,8 +608,13 @@ public abstract class HardwareRenderer {
|
||||
|
||||
DisplayList displayList = view.getDisplayList();
|
||||
if (displayList != null) {
|
||||
if (canvas.drawDisplayList(displayList)) {
|
||||
view.invalidate();
|
||||
if (canvas.drawDisplayList(displayList, mRedrawClip)) {
|
||||
if (mRedrawClip.isEmpty()) {
|
||||
view.invalidate();
|
||||
} else {
|
||||
view.getParent().invalidateChild(view, mRedrawClip);
|
||||
}
|
||||
mRedrawClip.setEmpty();
|
||||
}
|
||||
} else {
|
||||
// Shouldn't reach here
|
||||
@@ -646,8 +653,8 @@ public abstract class HardwareRenderer {
|
||||
private int checkCurrent() {
|
||||
// TODO: Don't check the current context when we have one per UI thread
|
||||
// TODO: Use a threadlocal flag to know whether the surface has changed
|
||||
if (sEgl.eglGetCurrentContext() != sEglContext ||
|
||||
sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW) != mEglSurface) {
|
||||
if (!sEglContext.equals(sEgl.eglGetCurrentContext()) ||
|
||||
!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
|
||||
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) {
|
||||
fallback(true);
|
||||
Log.e(LOG_TAG, "eglMakeCurrent failed " +
|
||||
|
||||
@@ -2585,7 +2585,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
}
|
||||
} else {
|
||||
child.mPrivateFlags &= ~DIRTY_MASK;
|
||||
((HardwareCanvas) canvas).drawDisplayList(displayList);
|
||||
((HardwareCanvas) canvas).drawDisplayList(displayList, null);
|
||||
}
|
||||
}
|
||||
} else if (cache != null) {
|
||||
|
||||
@@ -351,7 +351,8 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
private ZoomManager mZoomManager;
|
||||
|
||||
private Rect mGLRectViewport = new Rect();
|
||||
private final Rect mGLRectViewport = new Rect();
|
||||
private final Rect mViewRectViewport = new Rect();
|
||||
private boolean mGLViewportEmpty = false;
|
||||
|
||||
/**
|
||||
@@ -4152,7 +4153,7 @@ public class WebView extends AbsoluteLayout
|
||||
|
||||
if (canvas.isHardwareAccelerated()) {
|
||||
int functor = nativeGetDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
|
||||
getScale(), extras);
|
||||
mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
|
||||
((HardwareCanvas) canvas).callDrawGLFunction(functor);
|
||||
} else {
|
||||
DrawFilter df = null;
|
||||
@@ -5258,6 +5259,7 @@ public class WebView extends AbsoluteLayout
|
||||
// Then need to invert the Y axis, just for GL
|
||||
View rootView = getRootView();
|
||||
int rootViewHeight = rootView.getHeight();
|
||||
mViewRectViewport.set(mGLRectViewport);
|
||||
int savedWebViewBottom = mGLRectViewport.bottom;
|
||||
mGLRectViewport.bottom = rootViewHeight - mGLRectViewport.top - getVisibleTitleHeight();
|
||||
mGLRectViewport.top = rootViewHeight - savedWebViewBottom;
|
||||
@@ -5265,7 +5267,8 @@ public class WebView extends AbsoluteLayout
|
||||
} else {
|
||||
mGLViewportEmpty = true;
|
||||
}
|
||||
nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport);
|
||||
nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
|
||||
mGLViewportEmpty ? null : mViewRectViewport);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8531,8 +8534,9 @@ public class WebView extends AbsoluteLayout
|
||||
boolean splitIfNeeded);
|
||||
private native void nativeDumpDisplayTree(String urlOrNull);
|
||||
private native boolean nativeEvaluateLayersAnimations();
|
||||
private native int nativeGetDrawGLFunction(Rect rect, float scale, int extras);
|
||||
private native void nativeUpdateDrawGLFunction(Rect rect);
|
||||
private native int nativeGetDrawGLFunction(Rect rect, Rect viewRect,
|
||||
float scale, int extras);
|
||||
private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect);
|
||||
private native boolean nativeDrawGL(Rect rect, float scale, int extras);
|
||||
private native void nativeExtendSelection(int x, int y);
|
||||
private native int nativeFindAll(String findLower, String findUpper,
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include <DisplayListRenderer.h>
|
||||
#include <LayerRenderer.h>
|
||||
#include <OpenGLDebugRenderer.h>
|
||||
#include <OpenGLRenderer.h>
|
||||
#include <SkiaShader.h>
|
||||
#include <SkiaColorFilter.h>
|
||||
@@ -60,7 +59,6 @@ using namespace uirenderer;
|
||||
|
||||
// Debug
|
||||
#define DEBUG_RENDERER 0
|
||||
#define PROFILE_RENDERER 0
|
||||
|
||||
// Debug
|
||||
#if DEBUG_RENDERER
|
||||
@@ -99,11 +97,7 @@ static jboolean android_view_GLES20Canvas_preserveBackBuffer(JNIEnv* env, jobjec
|
||||
|
||||
static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject clazz) {
|
||||
RENDERER_LOGD("Create OpenGLRenderer");
|
||||
#if PROFILE_RENDERER
|
||||
return new OpenGLDebugRenderer;
|
||||
#else
|
||||
return new OpenGLRenderer;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
|
||||
@@ -139,7 +133,8 @@ static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
|
||||
|
||||
static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
|
||||
OpenGLRenderer* renderer, Functor *functor) {
|
||||
return renderer->callDrawGLFunction(functor);
|
||||
android::uirenderer::Rect dirty;
|
||||
return renderer->callDrawGLFunction(functor, dirty);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -503,8 +498,14 @@ static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env,
|
||||
}
|
||||
|
||||
static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
|
||||
jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList) {
|
||||
return renderer->drawDisplayList(displayList);
|
||||
jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList, jobject dirty) {
|
||||
android::uirenderer::Rect bounds;
|
||||
bool redraw = renderer->drawDisplayList(displayList, bounds);
|
||||
if (redraw && dirty != NULL) {
|
||||
env->CallVoidMethod(dirty, gRectClassInfo.set,
|
||||
int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
|
||||
}
|
||||
return redraw;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -663,7 +664,8 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nGetDisplayList", "(I)I", (void*) android_view_GLES20Canvas_getDisplayList },
|
||||
{ "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
|
||||
{ "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer },
|
||||
{ "nDrawDisplayList", "(II)Z", (void*) android_view_GLES20Canvas_drawDisplayList },
|
||||
{ "nDrawDisplayList", "(IILandroid/graphics/Rect;)Z",
|
||||
(void*) android_view_GLES20Canvas_drawDisplayList },
|
||||
|
||||
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
|
||||
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
Functor() {}
|
||||
virtual ~Functor() {}
|
||||
virtual status_t operator ()() { return true; }
|
||||
virtual status_t operator ()(float* data, uint32_t len) { return true; }
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
@@ -15,7 +15,6 @@ ifeq ($(USE_OPENGL_RENDERER),true)
|
||||
LayerCache.cpp \
|
||||
LayerRenderer.cpp \
|
||||
Matrix.cpp \
|
||||
OpenGLDebugRenderer.cpp \
|
||||
OpenGLRenderer.cpp \
|
||||
Patch.cpp \
|
||||
PatchCache.cpp \
|
||||
|
||||
@@ -166,7 +166,7 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
|
||||
void DisplayList::init() {
|
||||
}
|
||||
|
||||
bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
|
||||
bool needsInvalidate = false;
|
||||
TextContainer text;
|
||||
mReader.rewind();
|
||||
@@ -189,7 +189,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
case DrawGLFunction: {
|
||||
Functor *functor = (Functor *) getInt();
|
||||
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
|
||||
needsInvalidate |= renderer.callDrawGLFunction(functor);
|
||||
needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
|
||||
}
|
||||
break;
|
||||
case Save: {
|
||||
@@ -287,7 +287,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
DisplayList* displayList = getDisplayList();
|
||||
DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
|
||||
displayList, level + 1);
|
||||
needsInvalidate |= renderer.drawDisplayList(displayList, level + 1);
|
||||
needsInvalidate |= renderer.drawDisplayList(displayList, dirty, level + 1);
|
||||
}
|
||||
break;
|
||||
case DrawLayer: {
|
||||
@@ -589,7 +589,8 @@ void DisplayListRenderer::interrupt() {
|
||||
void DisplayListRenderer::resume() {
|
||||
}
|
||||
|
||||
bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
|
||||
bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
|
||||
// Ignore dirty during recording, it matters only when we replay
|
||||
addOp(DisplayList::DrawGLFunction);
|
||||
addInt((int) functor);
|
||||
return false; // No invalidate needed at record-time
|
||||
@@ -673,7 +674,9 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
|
||||
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
|
||||
}
|
||||
|
||||
bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
|
||||
// dirty is an out parameter and should not be recorded,
|
||||
// it matters only when replaying the display list
|
||||
addOp(DisplayList::DrawDisplayList);
|
||||
addDisplayList(displayList);
|
||||
return false;
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
|
||||
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
|
||||
|
||||
bool replay(OpenGLRenderer& renderer, uint32_t level = 0);
|
||||
bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
void prepareDirty(float left, float top, float right, float bottom, bool opaque);
|
||||
void finish();
|
||||
|
||||
bool callDrawGLFunction(Functor *functor);
|
||||
bool callDrawGLFunction(Functor *functor, Rect& dirty);
|
||||
|
||||
void interrupt();
|
||||
void resume();
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
|
||||
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
|
||||
bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
|
||||
void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
|
||||
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
|
||||
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "OpenGLRenderer"
|
||||
|
||||
#include <utils/StopWatch.h>
|
||||
|
||||
#include "OpenGLDebugRenderer.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
void OpenGLDebugRenderer::prepareDirty(float left, float top,
|
||||
float right, float bottom, bool opaque) {
|
||||
mPrimitivesCount = 0;
|
||||
LOGD("========= Frame start =========");
|
||||
OpenGLRenderer::prepareDirty(left, top, right, bottom, opaque);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::finish() {
|
||||
LOGD("========= Frame end =========");
|
||||
LOGD("Primitives draw count = %d", mPrimitivesCount);
|
||||
OpenGLRenderer::finish();
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("composeLayer");
|
||||
return OpenGLRenderer::composeLayer(current, previous);
|
||||
}
|
||||
|
||||
int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bottom,
|
||||
SkPaint* p, int flags) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("saveLayer");
|
||||
return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
|
||||
}
|
||||
|
||||
bool OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawDisplayList");
|
||||
return OpenGLRenderer::drawDisplayList(displayList);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawLayer");
|
||||
OpenGLRenderer::drawLayer(layer, x, y, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
|
||||
SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawBitmap");
|
||||
OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
|
||||
SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawBitmapMatrix");
|
||||
OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
|
||||
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
||||
float dstRight, float dstBottom, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawBitmapRect");
|
||||
OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
|
||||
dstLeft, dstTop, dstRight, dstBottom, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawPatch");
|
||||
OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
|
||||
left, top, right, bottom, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawColor(int color, SkXfermode::Mode mode) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawColor");
|
||||
OpenGLRenderer::drawColor(color, mode);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawRect(float left, float top, float right, float bottom,
|
||||
SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawRect");
|
||||
OpenGLRenderer::drawRect(left, top, right, bottom, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawRoundRect(float left, float top, float right, float bottom,
|
||||
float rx, float ry, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawRoundRect");
|
||||
OpenGLRenderer::drawRoundRect(left, top, right, bottom, rx, ry, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawCircle");
|
||||
OpenGLRenderer::drawCircle(x, y, radius, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawOval(float left, float top, float right, float bottom,
|
||||
SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawOval");
|
||||
OpenGLRenderer::drawOval(left, top, right, bottom, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawArc");
|
||||
OpenGLRenderer::drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawPath");
|
||||
OpenGLRenderer::drawPath(path, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawLines(float* points, int count, SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawLines");
|
||||
OpenGLRenderer::drawLines(points, count, paint);
|
||||
}
|
||||
|
||||
void OpenGLDebugRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
|
||||
SkPaint* paint) {
|
||||
mPrimitivesCount++;
|
||||
StopWatch w("drawText");
|
||||
OpenGLRenderer::drawText(text, bytesCount, count, x, y, paint);
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
|
||||
#define ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
|
||||
|
||||
#include "OpenGLRenderer.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Renderer
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class OpenGLDebugRenderer: public OpenGLRenderer {
|
||||
public:
|
||||
OpenGLDebugRenderer(): mPrimitivesCount(0) {
|
||||
}
|
||||
|
||||
~OpenGLDebugRenderer() {
|
||||
}
|
||||
|
||||
void prepareDirty(float left, float top, float right, float bottom, bool opaque);
|
||||
void finish();
|
||||
|
||||
int saveLayer(float left, float top, float right, float bottom,
|
||||
SkPaint* p, int flags);
|
||||
|
||||
bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
|
||||
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
|
||||
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
|
||||
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
|
||||
float srcRight, float srcBottom, float dstLeft, float dstTop,
|
||||
float dstRight, float dstBottom, SkPaint* paint);
|
||||
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
|
||||
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
|
||||
float left, float top, float right, float bottom, SkPaint* paint);
|
||||
void drawColor(int color, SkXfermode::Mode mode);
|
||||
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
||||
void drawRoundRect(float left, float top, float right, float bottom,
|
||||
float rx, float ry, SkPaint* paint);
|
||||
void drawCircle(float x, float y, float radius, SkPaint* paint);
|
||||
void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
|
||||
void drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
|
||||
void drawPath(SkPath* path, SkPaint* paint);
|
||||
void drawLines(float* points, int count, SkPaint* paint);
|
||||
void drawText(const char* text, int bytesCount, int count, float x, float y,
|
||||
SkPaint* paint);
|
||||
|
||||
protected:
|
||||
void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
|
||||
|
||||
private:
|
||||
uint32_t mPrimitivesCount;
|
||||
|
||||
}; // class OpenGLDebugRenderer
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
|
||||
@@ -210,7 +210,7 @@ void OpenGLRenderer::resume() {
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
|
||||
bool OpenGLRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
|
||||
interrupt();
|
||||
if (mDirtyClip) {
|
||||
setScissorFromClip();
|
||||
@@ -226,9 +226,16 @@ bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
|
||||
}
|
||||
#endif
|
||||
|
||||
status_t result = (*functor)();
|
||||
float bounds[4];
|
||||
status_t result = (*functor)(&bounds[0], 4);
|
||||
|
||||
if (result != 0) {
|
||||
Rect localDirty(bounds[0], bounds[1], bounds[2], bounds[3]);
|
||||
dirty.unionWith(localDirty);
|
||||
}
|
||||
|
||||
resume();
|
||||
return (result == 0) ? false : true;
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1057,11 +1064,11 @@ void OpenGLRenderer::finishDrawTexture() {
|
||||
// Drawing
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
|
||||
bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
|
||||
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
|
||||
// will be performed by the display list itself
|
||||
if (displayList) {
|
||||
return displayList->replay(*this, level);
|
||||
return displayList->replay(*this, dirty, level);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1522,7 +1529,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Handle paint->getTextScaleX()
|
||||
const float oldX = x;
|
||||
const float oldY = y;
|
||||
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
|
||||
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
virtual void interrupt();
|
||||
virtual void resume();
|
||||
|
||||
virtual bool callDrawGLFunction(Functor *functor);
|
||||
virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
|
||||
|
||||
int getSaveCount() const;
|
||||
virtual int save(int flags);
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
bool quickReject(float left, float top, float right, float bottom);
|
||||
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
|
||||
|
||||
virtual bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
|
||||
virtual bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
|
||||
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
|
||||
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
|
||||
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
|
||||
|
||||
@@ -42,6 +42,17 @@ struct ShadowText {
|
||||
|
||||
textSize = paint->getTextSize();
|
||||
typeface = paint->getTypeface();
|
||||
|
||||
flags = 0;
|
||||
if (paint->isFakeBoldText()) {
|
||||
flags |= Font::kFakeBold;
|
||||
}
|
||||
|
||||
const float skewX = paint->getTextSkewX();
|
||||
italicStyle = *(uint32_t*) &skewX;
|
||||
|
||||
const float scaleXFloat = paint->getTextScaleX();
|
||||
scaleX = *(uint32_t*) &scaleXFloat;
|
||||
}
|
||||
|
||||
~ShadowText() {
|
||||
@@ -51,6 +62,9 @@ struct ShadowText {
|
||||
uint32_t len;
|
||||
float textSize;
|
||||
SkTypeface* typeface;
|
||||
uint32_t flags;
|
||||
uint32_t italicStyle;
|
||||
uint32_t scaleX;
|
||||
const char16_t* text;
|
||||
String16 str;
|
||||
|
||||
@@ -65,7 +79,13 @@ struct ShadowText {
|
||||
LTE_INT(radius) {
|
||||
LTE_FLOAT(textSize) {
|
||||
LTE_INT(typeface) {
|
||||
return strncmp16(text, rhs.text, len >> 1) < 0;
|
||||
LTE_INT(flags) {
|
||||
LTE_INT(italicStyle) {
|
||||
LTE_INT(scaleX) {
|
||||
return strncmp16(text, rhs.text, len >> 1) < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,12 @@ public class TextActivity extends Activity {
|
||||
mScaledPaint = new Paint();
|
||||
mScaledPaint.setAntiAlias(true);
|
||||
mScaledPaint.setTextSize(16.0f);
|
||||
mScaledPaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff00ff00);
|
||||
|
||||
mSkewPaint = new Paint();
|
||||
mSkewPaint.setAntiAlias(true);
|
||||
mSkewPaint.setTextSize(16.0f);
|
||||
mSkewPaint.setTextSize(16.0f);
|
||||
mSkewPaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,11 +108,11 @@ public class TextActivity extends Activity {
|
||||
mStrikePaint.setUnderlineText(true);
|
||||
|
||||
mSkewPaint.setTextSkewX(-0.25f);
|
||||
canvas.drawText("Hello OpenGL renderer!", 680, 200, mSkewPaint);
|
||||
canvas.drawText("Hello OpenGL renderer!", 980, 200, mSkewPaint);
|
||||
mSkewPaint.setTextSkewX(0.5f);
|
||||
canvas.drawText("Hello OpenGL renderer!", 680, 230, mSkewPaint);
|
||||
canvas.drawText("Hello OpenGL renderer!", 980, 230, mSkewPaint);
|
||||
mSkewPaint.setTextSkewX(0.0f);
|
||||
canvas.drawText("Hello OpenGL renderer!", 680, 260, mSkewPaint);
|
||||
canvas.drawText("Hello OpenGL renderer!", 980, 260, mSkewPaint);
|
||||
|
||||
mScaledPaint.setTextScaleX(0.5f);
|
||||
canvas.drawText("Hello OpenGL renderer!", 500, 200, mScaledPaint);
|
||||
@@ -125,4 +127,4 @@ public class TextActivity extends Activity {
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user