Correctly set the viewport in layers.

Bug #2919295

Change-Id: I16ce79ab0d5747cb01c6c1abe531da3dfd93fb54
This commit is contained in:
Romain Guy
2010-08-17 11:37:00 -07:00
parent 0a41749953
commit 1d83e1981c
7 changed files with 142 additions and 71 deletions

View File

@@ -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("]");

View File

@@ -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++;

View File

@@ -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.
*/

View File

@@ -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);
}

View 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>

View 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>

View File

@@ -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);
}
}