Merge "Adjust light source for window position" into mnc-dev

This commit is contained in:
Alan Viverette
2015-05-15 18:31:40 +00:00
committed by Android (Google) Code Review
13 changed files with 105 additions and 53 deletions

View File

@@ -260,7 +260,7 @@ public abstract class HardwareRenderer {
/** /**
* Gets the current width of the surface. This is the width that the surface * Gets the current width of the surface. This is the width that the surface
* was last set to in a call to {@link #setup(int, int, Rect)}. * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
* *
* @return the current width of the surface * @return the current width of the surface
*/ */
@@ -268,7 +268,7 @@ public abstract class HardwareRenderer {
/** /**
* Gets the current height of the surface. This is the height that the surface * Gets the current height of the surface. This is the height that the surface
* was last set to in a call to {@link #setup(int, int, Rect)}. * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
* *
* @return the current width of the surface * @return the current width of the surface
*/ */
@@ -373,19 +373,20 @@ public abstract class HardwareRenderer {
* *
* @param width The width of the drawing surface. * @param width The width of the drawing surface.
* @param height The height of the drawing surface. * @param height The height of the drawing surface.
* @param attachInfo Information about the window.
* @param surface The surface to hardware accelerate * @param surface The surface to hardware accelerate
* @param surfaceInsets The drawing surface insets to apply * @param surfaceInsets The drawing surface insets to apply
* *
* @return true if the surface was initialized, false otherwise. Returning * @return true if the surface was initialized, false otherwise. Returning
* false might mean that the surface was already initialized. * false might mean that the surface was already initialized.
*/ */
boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets) boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
throws OutOfResourcesException { Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
if (isRequested()) { if (isRequested()) {
// We lost the gl context, so recreate it. // We lost the gl context, so recreate it.
if (!isEnabled()) { if (!isEnabled()) {
if (initialize(surface)) { if (initialize(surface)) {
setup(width, height, surfaceInsets); setup(width, height, attachInfo, surfaceInsets);
return true; return true;
} }
} }
@@ -398,9 +399,17 @@ public abstract class HardwareRenderer {
* *
* @param width The width of the drawing surface. * @param width The width of the drawing surface.
* @param height The height of the drawing surface. * @param height The height of the drawing surface.
* @param attachInfo Information about the window.
* @param surfaceInsets The drawing surface insets to apply * @param surfaceInsets The drawing surface insets to apply
*/ */
abstract void setup(int width, int height, Rect surfaceInsets); abstract void setup(int width, int height, View.AttachInfo attachInfo, Rect surfaceInsets);
/**
* Updates the light position based on the position of the window.
*
* @param attachInfo Information about the window.
*/
abstract void setLightCenter(View.AttachInfo attachInfo);
/** /**
* Optional, sets the name of the renderer. Useful for debugging purposes. * Optional, sets the name of the renderer. Useful for debugging purposes.

View File

@@ -19,11 +19,10 @@ package android.view;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@@ -31,7 +30,6 @@ import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.Trace; import android.os.Trace;
import android.util.Log; import android.util.Log;
import android.util.LongSparseArray;
import android.view.Surface.OutOfResourcesException; import android.view.Surface.OutOfResourcesException;
import android.view.View.AttachInfo; import android.view.View.AttachInfo;
@@ -41,8 +39,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashSet;
/** /**
* Hardware renderer that proxies the rendering to a render thread. Most calls * Hardware renderer that proxies the rendering to a render thread. Most calls
@@ -197,10 +193,10 @@ public class ThreadedRenderer extends HardwareRenderer {
} }
@Override @Override
void setup(int width, int height, Rect surfaceInsets) { void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
final float lightX = width / 2.0f;
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
|| surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) { || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
mHasInsets = true; mHasInsets = true;
@@ -218,10 +214,23 @@ public class ThreadedRenderer extends HardwareRenderer {
mSurfaceWidth = width; mSurfaceWidth = width;
mSurfaceHeight = height; mSurfaceHeight = height;
} }
mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight); mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
lightX, mLightY, mLightZ, mLightRadius,
mAmbientShadowAlpha, mSpotShadowAlpha); mAmbientShadowAlpha, mSpotShadowAlpha);
setLightCenter(attachInfo);
}
@Override
void setLightCenter(AttachInfo attachInfo) {
// Adjust light position for window offsets.
final Point displaySize = attachInfo.mPoint;
attachInfo.mDisplay.getRealSize(displaySize);
final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
final float lightY = mLightY - attachInfo.mWindowTop;
nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
} }
@Override @Override
@@ -500,8 +509,9 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native void nUpdateSurface(long nativeProxy, Surface window); private static native void nUpdateSurface(long nativeProxy, Surface window);
private static native boolean nPauseSurface(long nativeProxy, Surface window); private static native boolean nPauseSurface(long nativeProxy, Surface window);
private static native void nSetup(long nativeProxy, int width, int height, private static native void nSetup(long nativeProxy, int width, int height,
float lightX, float lightY, float lightZ, float lightRadius, float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
int ambientShadowAlpha, int spotShadowAlpha); private static native void nSetLightCenter(long nativeProxy,
float lightX, float lightY, float lightZ);
private static native void nSetOpaque(long nativeProxy, boolean opaque); private static native void nSetOpaque(long nativeProxy, boolean opaque);
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size); private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy); private static native void nDestroy(long nativeProxy);

View File

@@ -1813,15 +1813,15 @@ public final class ViewRootImpl implements ViewParent,
} }
} }
if (mAttachInfo.mHardwareRenderer != null && final HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer;
mAttachInfo.mHardwareRenderer.isEnabled()) { if (hardwareRenderer != null && hardwareRenderer.isEnabled()) {
if (hwInitialized || if (hwInitialized
mWidth != mAttachInfo.mHardwareRenderer.getWidth() || || mWidth != hardwareRenderer.getWidth()
mHeight != mAttachInfo.mHardwareRenderer.getHeight()) { || mHeight != hardwareRenderer.getHeight()) {
mAttachInfo.mHardwareRenderer.setup( hardwareRenderer.setup(mWidth, mHeight, mAttachInfo,
mWidth, mHeight, mWindowAttributes.surfaceInsets); mWindowAttributes.surfaceInsets);
if (!hwInitialized) { if (!hwInitialized) {
mAttachInfo.mHardwareRenderer.invalidate(mSurface); hardwareRenderer.invalidate(mSurface);
mFullRedrawNeeded = true; mFullRedrawNeeded = true;
} }
} }
@@ -1897,6 +1897,11 @@ public final class ViewRootImpl implements ViewParent,
} }
mAttachInfo.mWindowLeft = frame.left; mAttachInfo.mWindowLeft = frame.left;
mAttachInfo.mWindowTop = frame.top; mAttachInfo.mWindowTop = frame.top;
// Update the light position for the new window offsets.
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
}
} }
} }
@@ -2605,7 +2610,7 @@ public final class ViewRootImpl implements ViewParent,
try { try {
mAttachInfo.mHardwareRenderer.initializeIfNeeded( mAttachInfo.mHardwareRenderer.initializeIfNeeded(
mWidth, mHeight, mSurface, surfaceInsets); mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
} catch (OutOfResourcesException e) { } catch (OutOfResourcesException e) {
handleOutOfResourcesException(e); handleOutOfResourcesException(e);
return; return;
@@ -3300,7 +3305,7 @@ public final class ViewRootImpl implements ViewParent,
final WindowManager.LayoutParams lp = mWindowAttributes; final WindowManager.LayoutParams lp = mWindowAttributes;
final Rect surfaceInsets = lp != null ? lp.surfaceInsets : null; final Rect surfaceInsets = lp != null ? lp.surfaceInsets : null;
mAttachInfo.mHardwareRenderer.initializeIfNeeded( mAttachInfo.mHardwareRenderer.initializeIfNeeded(
mWidth, mHeight, mSurface, surfaceInsets); mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
} catch (OutOfResourcesException e) { } catch (OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException locking surface", e); Log.e(TAG, "OutOfResourcesException locking surface", e);
try { try {

View File

@@ -483,7 +483,8 @@ static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfaceP
proxy->initialize(surface); proxy->initialize(surface);
// Shadows can't be used via this interface, so just set the light source // Shadows can't be used via this interface, so just set the light source
// to all 0s. (and width & height are unused, TODO remove them) // to all 0s. (and width & height are unused, TODO remove them)
proxy->setup(0, 0, (Vector3){0, 0, 0}, 0, 0, 0); proxy->setup(0, 0, 0, 0, 0);
proxy->setLightCenter((Vector3){0, 0, 0});
return (jlong) proxy; return (jlong) proxy;
} }

View File

@@ -290,12 +290,15 @@ static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject
} }
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
jint width, jint height, jint width, jint height, jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
jfloat lightX, jfloat lightY, jfloat lightZ, jfloat lightRadius,
jint ambientShadowAlpha, jint spotShadowAlpha, jfloat density) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
proxy->setup(width, height, (Vector3){lightX, lightY, lightZ}, lightRadius, proxy->setup(width, height, lightRadius, ambientShadowAlpha, spotShadowAlpha);
ambientShadowAlpha, spotShadowAlpha); }
static void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz,
jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
proxy->setLightCenter((Vector3){lightX, lightY, lightZ});
} }
static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz, static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
@@ -461,7 +464,8 @@ static JNINativeMethod gMethods[] = {
{ "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize }, { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
{ "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface }, { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
{ "nSetup", "(JIIFFFFII)V", (void*) android_view_ThreadedRenderer_setup }, { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque }, { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
{ "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy }, { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy },

View File

@@ -90,8 +90,10 @@ void Layer::updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer) {
// re-init renderer's light position, based upon last cached location in window // re-init renderer's light position, based upon last cached location in window
Vector3 lightPos = rootRenderer.getLightCenter(); Vector3 lightPos = rootRenderer.getLightCenter();
cachedInvTransformInWindow.mapPoint3d(lightPos); cachedInvTransformInWindow.mapPoint3d(lightPos);
renderer->initLight(lightPos, rootRenderer.getLightRadius(), renderer->initLight(rootRenderer.getLightRadius(),
rootRenderer.getAmbientShadowAlpha(), rootRenderer.getSpotShadowAlpha()); rootRenderer.getAmbientShadowAlpha(),
rootRenderer.getSpotShadowAlpha());
renderer->setLightCenter(lightPos);
rendererLightPosDirty = false; rendererLightPosDirty = false;
} }
} }

View File

@@ -94,14 +94,17 @@ void OpenGLRenderer::initProperties() {
} }
} }
void OpenGLRenderer::initLight(const Vector3& lightCenter, float lightRadius, void OpenGLRenderer::initLight(float lightRadius, uint8_t ambientShadowAlpha,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { uint8_t spotShadowAlpha) {
mLightCenter = lightCenter;
mLightRadius = lightRadius; mLightRadius = lightRadius;
mAmbientShadowAlpha = ambientShadowAlpha; mAmbientShadowAlpha = ambientShadowAlpha;
mSpotShadowAlpha = spotShadowAlpha; mSpotShadowAlpha = spotShadowAlpha;
} }
void OpenGLRenderer::setLightCenter(const Vector3& lightCenter) {
mLightCenter = lightCenter;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Setup // Setup
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@@ -127,8 +127,9 @@ public:
void setViewport(int width, int height) { mState.setViewport(width, height); } void setViewport(int width, int height) { mState.setViewport(width, height); }
void initProperties(); void initProperties();
void initLight(const Vector3& lightCenter, float lightRadius, void initLight(float lightRadius, uint8_t ambientShadowAlpha,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); uint8_t spotShadowAlpha);
void setLightCenter(const Vector3& lightCenter);
/* /*
* Prepares the renderer to draw a frame. This method must be invoked * Prepares the renderer to draw a frame. This method must be invoked

View File

@@ -127,10 +127,15 @@ bool CanvasContext::pauseSurface(ANativeWindow* window) {
} }
// TODO: don't pass viewport size, it's automatic via EGL // TODO: don't pass viewport size, it's automatic via EGL
void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius, void CanvasContext::setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
if (!mCanvas) return; if (!mCanvas) return;
mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha); mCanvas->initLight(lightRadius, ambientShadowAlpha, spotShadowAlpha);
}
void CanvasContext::setLightCenter(const Vector3& lightCenter) {
if (!mCanvas) return;
mCanvas->setLightCenter(lightCenter);
} }
void CanvasContext::setOpaque(bool opaque) { void CanvasContext::setOpaque(bool opaque) {

View File

@@ -72,8 +72,9 @@ public:
bool pauseSurface(ANativeWindow* window); bool pauseSurface(ANativeWindow* window);
bool hasSurface() { return mNativeWindow.get(); } bool hasSurface() { return mNativeWindow.get(); }
void setup(int width, int height, const Vector3& lightCenter, float lightRadius, void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
void setLightCenter(const Vector3& lightCenter);
void setOpaque(bool opaque); void setOpaque(bool opaque);
void makeCurrent(); void makeCurrent();
void processLayerUpdate(DeferredLayerUpdater* layerUpdater); void processLayerUpdate(DeferredLayerUpdater* layerUpdater);

View File

@@ -172,27 +172,37 @@ bool RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
return (bool) postAndWait(task); return (bool) postAndWait(task);
} }
CREATE_BRIDGE7(setup, CanvasContext* context, int width, int height, CREATE_BRIDGE6(setup, CanvasContext* context, int width, int height,
Vector3 lightCenter, float lightRadius, float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { args->context->setup(args->width, args->height, args->lightRadius,
args->context->setup(args->width, args->height, args->lightCenter, args->lightRadius,
args->ambientShadowAlpha, args->spotShadowAlpha); args->ambientShadowAlpha, args->spotShadowAlpha);
return nullptr; return nullptr;
} }
void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float lightRadius, void RenderProxy::setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
SETUP_TASK(setup); SETUP_TASK(setup);
args->context = mContext; args->context = mContext;
args->width = width; args->width = width;
args->height = height; args->height = height;
args->lightCenter = lightCenter;
args->lightRadius = lightRadius; args->lightRadius = lightRadius;
args->ambientShadowAlpha = ambientShadowAlpha; args->ambientShadowAlpha = ambientShadowAlpha;
args->spotShadowAlpha = spotShadowAlpha; args->spotShadowAlpha = spotShadowAlpha;
post(task); post(task);
} }
CREATE_BRIDGE2(setLightCenter, CanvasContext* context, Vector3 lightCenter) {
args->context->setLightCenter(args->lightCenter);
return nullptr;
}
void RenderProxy::setLightCenter(const Vector3& lightCenter) {
SETUP_TASK(setLightCenter);
args->context = mContext;
args->lightCenter = lightCenter;
post(task);
}
CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) { CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) {
args->context->setOpaque(args->opaque); args->context->setOpaque(args->opaque);
return nullptr; return nullptr;

View File

@@ -70,8 +70,9 @@ public:
ANDROID_API bool initialize(const sp<ANativeWindow>& window); ANDROID_API bool initialize(const sp<ANativeWindow>& window);
ANDROID_API void updateSurface(const sp<ANativeWindow>& window); ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window); ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window);
ANDROID_API void setup(int width, int height, const Vector3& lightCenter, float lightRadius, ANDROID_API void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
ANDROID_API void setLightCenter(const Vector3& lightCenter);
ANDROID_API void setOpaque(bool opaque); ANDROID_API void setOpaque(bool opaque);
ANDROID_API int64_t* frameInfo(); ANDROID_API int64_t* frameInfo();
ANDROID_API int syncAndDrawFrame(); ANDROID_API int syncAndDrawFrame();

View File

@@ -92,8 +92,8 @@ public:
proxy->loadSystemProperties(); proxy->loadSystemProperties();
proxy->initialize(surface); proxy->initialize(surface);
float lightX = width / 2.0; float lightX = width / 2.0;
proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)}, proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
dp(800.0f), 255 * 0.075, 255 * 0.15); proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
android::uirenderer::Rect DUMMY; android::uirenderer::Rect DUMMY;