Correctly set the viewport in layers.
Bug #2919295 Change-Id: I16ce79ab0d5747cb01c6c1abe531da3dfd93fb54
This commit is contained in:
@@ -260,10 +260,10 @@ void Matrix4::mapRect(Rect& r) const {
|
||||
}
|
||||
|
||||
float vertices[] = {
|
||||
r.left, r.top,
|
||||
r.right, r.top,
|
||||
r.right, r.bottom,
|
||||
r.left, r.bottom
|
||||
r.left, r.top,
|
||||
r.right, r.top,
|
||||
r.right, r.bottom,
|
||||
r.left, r.bottom
|
||||
};
|
||||
|
||||
float x, y, z;
|
||||
@@ -297,8 +297,8 @@ void Matrix4::mapRect(Rect& r) const {
|
||||
|
||||
void Matrix4::dump() const {
|
||||
LOGD("Matrix4[simple=%d", mSimpleMatrix);
|
||||
LOGD(" %f %f %f %f", data[kScaleX], data[kSkewX], data[ 8], data[kTranslateX]);
|
||||
LOGD(" %f %f %f %f", data[kSkewY], data[kScaleY], data[ 9], data[kTranslateY]);
|
||||
LOGD(" %f %f %f %f", data[kScaleX], data[kSkewX], data[8], data[kTranslateX]);
|
||||
LOGD(" %f %f %f %f", data[kSkewY], data[kScaleY], data[9], data[kTranslateY]);
|
||||
LOGD(" %f %f %f %f", data[2], data[6], data[kScaleZ], data[kTranslateZ]);
|
||||
LOGD(" %f %f %f %f", data[kPerspective0], data[kPerspective1], data[11], data[kPerspective2]);
|
||||
LOGD("]");
|
||||
|
||||
@@ -183,12 +183,12 @@ OpenGLRenderer::~OpenGLRenderer() {
|
||||
|
||||
void OpenGLRenderer::setViewport(int width, int height) {
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFirstSnapshot->height = height;
|
||||
mFirstSnapshot->viewport.set(0, 0, width, height);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::prepare() {
|
||||
@@ -254,6 +254,8 @@ bool OpenGLRenderer::restoreSnapshot() {
|
||||
sp<Snapshot> previous = mSnapshot->previous;
|
||||
|
||||
if (restoreOrtho) {
|
||||
Rect& r = previous->viewport;
|
||||
glViewport(r.left, r.top, r.right, r.bottom);
|
||||
mOrthoMatrix.load(current->orthoMatrix);
|
||||
}
|
||||
|
||||
@@ -267,39 +269,6 @@ bool OpenGLRenderer::restoreSnapshot() {
|
||||
return restoreClip;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
if (!current->layer) {
|
||||
LOGE("Attempting to compose a layer that does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
// Unbind current FBO and restore previous one
|
||||
// Most of the time, previous->fbo will be 0 to bind the default buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
|
||||
|
||||
// Restore the clip from the previous snapshot
|
||||
const Rect& clip = previous->clipRect;
|
||||
glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
|
||||
|
||||
Layer* layer = current->layer;
|
||||
const Rect& rect = layer->layer;
|
||||
|
||||
drawTextureRect(rect.left, rect.top, rect.right, rect.bottom,
|
||||
layer->texture, layer->alpha, layer->mode, layer->blend);
|
||||
|
||||
LayerSize size(rect.getWidth(), rect.getHeight());
|
||||
// Failing to add the layer to the cache should happen only if the
|
||||
// layer is too large
|
||||
if (!mLayerCache.put(size, layer)) {
|
||||
LAYER_LOGD("Deleting layer");
|
||||
|
||||
glDeleteFramebuffers(1, &layer->fbo);
|
||||
glDeleteTextures(1, &layer->texture);
|
||||
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Layers
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -366,21 +335,58 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
|
||||
|
||||
// Creates a new snapshot to draw into the FBO
|
||||
saveSnapshot();
|
||||
// TODO: This doesn't preserve other transformations (check Skia first)
|
||||
|
||||
mSnapshot->transform.loadTranslate(-left, -top, 0.0f);
|
||||
mSnapshot->setClip(0.0f, 0.0f, right - left, bottom - top);
|
||||
mSnapshot->viewport.set(0.0f, 0.0f, right - left, bottom - top);
|
||||
mSnapshot->height = bottom - top;
|
||||
|
||||
setScissorFromClip();
|
||||
|
||||
mSnapshot->flags = Snapshot::kFlagDirtyOrtho | Snapshot::kFlagClipSet;
|
||||
mSnapshot->orthoMatrix.load(mOrthoMatrix);
|
||||
|
||||
// Change the ortho projection
|
||||
mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f);
|
||||
glViewport(0, 0, right - left, bottom - top);
|
||||
// Don't flip the FBO, it will get flipped when drawing back to the framebuffer
|
||||
mOrthoMatrix.loadOrtho(0.0f, right - left, 0.0f, bottom - top, -1.0f, 1.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
if (!current->layer) {
|
||||
LOGE("Attempting to compose a layer that does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
// Unbind current FBO and restore previous one
|
||||
// Most of the time, previous->fbo will be 0 to bind the default buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
|
||||
|
||||
// Restore the clip from the previous snapshot
|
||||
const Rect& clip = previous->clipRect;
|
||||
glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
|
||||
|
||||
Layer* layer = current->layer;
|
||||
const Rect& rect = layer->layer;
|
||||
|
||||
drawTextureRect(rect.left, rect.top, rect.right, rect.bottom,
|
||||
layer->texture, layer->alpha, layer->mode, layer->blend);
|
||||
|
||||
LayerSize size(rect.getWidth(), rect.getHeight());
|
||||
// Failing to add the layer to the cache should happen only if the
|
||||
// layer is too large
|
||||
if (!mLayerCache.put(size, layer)) {
|
||||
LAYER_LOGD("Deleting layer");
|
||||
|
||||
glDeleteFramebuffers(1, &layer->fbo);
|
||||
glDeleteTextures(1, &layer->texture);
|
||||
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Transforms
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -424,14 +430,9 @@ const Rect& OpenGLRenderer::getClipBounds() {
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
|
||||
SkRect sr;
|
||||
sr.set(left, top, right, bottom);
|
||||
Rect r(left, top, right, bottom);
|
||||
mSnapshot->transform.mapRect(r);
|
||||
|
||||
SkMatrix m;
|
||||
mSnapshot->transform.copyTo(m);
|
||||
m.mapRect(&sr);
|
||||
|
||||
Rect r(sr.fLeft, sr.fTop, sr.fRight, sr.fBottom);
|
||||
return !mSnapshot->clipRect.intersects(r);
|
||||
}
|
||||
|
||||
@@ -759,7 +760,6 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
|
||||
mModelView.loadIdentity();
|
||||
}
|
||||
mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
|
||||
|
||||
glUniform4f(mCurrentProgram->color, r, g, b, a);
|
||||
|
||||
textureUnit++;
|
||||
|
||||
@@ -57,7 +57,8 @@ public:
|
||||
flags(0),
|
||||
previous(s),
|
||||
layer(NULL),
|
||||
fbo(s->fbo) {
|
||||
fbo(s->fbo),
|
||||
viewport(s->viewport) {
|
||||
if ((s->flags & Snapshot::kFlagClipSet) &&
|
||||
!(s->flags & Snapshot::kFlagDirtyLocalClip)) {
|
||||
localClip.set(s->localClip);
|
||||
@@ -179,6 +180,11 @@ public:
|
||||
Layer* layer;
|
||||
GLuint fbo;
|
||||
|
||||
/**
|
||||
* Current viewport.
|
||||
*/
|
||||
Rect viewport;
|
||||
|
||||
/**
|
||||
* Contains the previous ortho matrix.
|
||||
*/
|
||||
|
||||
@@ -47,7 +47,7 @@ struct ShadowText {
|
||||
|
||||
ShadowText(const ShadowText& shadow):
|
||||
paint(shadow.paint), radius(shadow.radius), len(shadow.len), hash(shadow.hash) {
|
||||
text = new char[len];
|
||||
text = new char[shadow.len];
|
||||
memcpy(text, shadow.text, shadow.len);
|
||||
}
|
||||
|
||||
|
||||
33
tests/HwAccelerationTest/res/layout/stack.xml
Normal file
33
tests/HwAccelerationTest/res/layout/stack.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingBottom="0dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:focusable="true">
|
||||
<StackView
|
||||
android:id="@+id/stack_view"
|
||||
android:layout_width="348px"
|
||||
android:layout_height="374px"
|
||||
android:layout_gravity="center"
|
||||
android:background="#00000000"
|
||||
android:cacheColorHint="#00000000"
|
||||
android:autoStart="true" />
|
||||
</FrameLayout>
|
||||
38
tests/HwAccelerationTest/res/layout/stack_item.xml
Normal file
38
tests/HwAccelerationTest/res/layout/stack_item.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/stack_item"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<ImageView android:id="@+id/textview_icon"
|
||||
android:layout_height="250dip"
|
||||
android:layout_width="250dip"
|
||||
android:layout_gravity="center" />
|
||||
<TextView android:id="@+id/mini_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
@@ -19,14 +19,13 @@ package com.google.android.test.hwui;
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.StackView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public class StackActivity extends Activity {
|
||||
@@ -34,32 +33,27 @@ public class StackActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
StackView stack = new StackView(this);
|
||||
setContentView(R.layout.stack);
|
||||
|
||||
StackView stack = (StackView) findViewById(R.id.stack_view);
|
||||
stack.setAdapter(new ArrayAdapter<Drawable>(this, android.R.layout.simple_list_item_1,
|
||||
android.R.id.text1, new Drawable[] {
|
||||
getResources().getDrawable(R.drawable.sunset1),
|
||||
getResources().getDrawable(R.drawable.sunset2),
|
||||
getResources().getDrawable(R.drawable.sunset1),
|
||||
getResources().getDrawable(R.drawable.sunset2),
|
||||
getResources().getDrawable(R.drawable.sunset1),
|
||||
getResources().getDrawable(R.drawable.sunset2)
|
||||
}) {
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ImageView image;
|
||||
if (convertView == null) {
|
||||
image = new ImageView(StackActivity.this);
|
||||
} else {
|
||||
image = (ImageView) convertView;
|
||||
View item = convertView;
|
||||
if (item == null) {
|
||||
item = LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.stack_item, null, false);
|
||||
}
|
||||
image.setImageDrawable(getItem(position % getCount()));
|
||||
return image;
|
||||
((ImageView) item.findViewById(R.id.textview_icon)).setImageDrawable(
|
||||
getItem(position % getCount()));
|
||||
((TextView) item.findViewById(R.id.mini_text)).setText("" + position);
|
||||
return item;
|
||||
}
|
||||
});
|
||||
stack.setDisplayedChild(0);
|
||||
|
||||
FrameLayout layout = new FrameLayout(this);
|
||||
layout.addView(stack, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER));
|
||||
setContentView(layout);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user