зеркало из https://github.com/mozilla/pjs.git
Bug 708307 - Decouple texture size from tile size. r=pcwalton a=android-only
This removes the hard-coded limit of 1024x2048 tile sizes, and allows for arbitrary tile-sizes. It will still only allocate texture sizes in powers of two, however. It replaces the tile size with a buffered-area size, which can be re-allocated as the screen dimensions change.
This commit is contained in:
Родитель
4e929653f5
Коммит
660420952d
|
@ -491,15 +491,6 @@ public class GeckoAppShell
|
|||
/*
|
||||
* The Gecko-side API: API methods that Gecko calls
|
||||
*/
|
||||
public static void scheduleRedraw() {
|
||||
// Redraw everything
|
||||
Rect rect = new Rect(0, 0, LayerController.TILE_WIDTH, LayerController.TILE_HEIGHT);
|
||||
GeckoEvent event = new GeckoEvent(GeckoEvent.DRAW, rect);
|
||||
event.mNativeWindow = 0;
|
||||
sendEventToGecko(event);
|
||||
}
|
||||
|
||||
|
||||
public static void notifyIME(int type, int state) {
|
||||
mInputConnection.notifyIME(type, state);
|
||||
}
|
||||
|
|
|
@ -46,21 +46,22 @@ import java.nio.ByteBuffer;
|
|||
/** A Cairo image that simply saves a buffer of pixel data. */
|
||||
public class BufferedCairoImage extends CairoImage {
|
||||
private ByteBuffer mBuffer;
|
||||
private int mWidth, mHeight, mFormat;
|
||||
private IntSize mSize;
|
||||
private int mFormat;
|
||||
private boolean mNeedToFreeBuffer = false;
|
||||
|
||||
/** Creates a buffered Cairo image from a byte buffer. */
|
||||
public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
|
||||
mBuffer = inBuffer; mWidth = inWidth; mHeight = inHeight; mFormat = inFormat;
|
||||
mBuffer = inBuffer; mSize = new IntSize(inWidth, inHeight); mFormat = inFormat;
|
||||
}
|
||||
|
||||
/** Creates a buffered Cairo image from an Android bitmap. */
|
||||
public BufferedCairoImage(Bitmap bitmap) {
|
||||
mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
|
||||
mWidth = bitmap.getWidth();
|
||||
mHeight = bitmap.getHeight();
|
||||
mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
|
||||
mNeedToFreeBuffer = true;
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 4);
|
||||
// XXX Why is this * 4? Shouldn't it depend on mFormat?
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mSize.getArea() * 4);
|
||||
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
|
||||
}
|
||||
|
||||
|
@ -78,9 +79,7 @@ public class BufferedCairoImage extends CairoImage {
|
|||
@Override
|
||||
public ByteBuffer getBuffer() { return mBuffer; }
|
||||
@Override
|
||||
public int getWidth() { return mWidth; }
|
||||
@Override
|
||||
public int getHeight() { return mHeight; }
|
||||
public IntSize getSize() { return mSize; }
|
||||
@Override
|
||||
public int getFormat() { return mFormat; }
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@ import java.nio.ByteBuffer;
|
|||
public abstract class CairoImage {
|
||||
public abstract ByteBuffer getBuffer();
|
||||
|
||||
public abstract int getWidth();
|
||||
public abstract int getHeight();
|
||||
public abstract IntSize getSize();
|
||||
public abstract int getFormat();
|
||||
|
||||
public static final int FORMAT_INVALID = -1;
|
||||
|
|
|
@ -72,8 +72,9 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
private static final String LOGTAG = "GeckoSoftwareLayerClient";
|
||||
|
||||
private Context mContext;
|
||||
private int mWidth, mHeight, mFormat;
|
||||
private int mFormat;
|
||||
private IntSize mScreenSize, mViewportSize;
|
||||
private IntSize mBufferSize;
|
||||
private ByteBuffer mBuffer;
|
||||
private final SingleTileLayer mTileLayer;
|
||||
|
||||
|
@ -97,21 +98,15 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
public GeckoSoftwareLayerClient(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mWidth = LayerController.TILE_WIDTH;
|
||||
mHeight = LayerController.TILE_HEIGHT;
|
||||
mScreenSize = new IntSize(0, 0);
|
||||
mBufferSize = new IntSize(0, 0);
|
||||
mFormat = CairoImage.FORMAT_RGB16_565;
|
||||
|
||||
mScreenSize = new IntSize(1, 1);
|
||||
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 2);
|
||||
|
||||
mCairoImage = new CairoImage() {
|
||||
@Override
|
||||
public ByteBuffer getBuffer() { return mBuffer; }
|
||||
@Override
|
||||
public int getWidth() { return mWidth; }
|
||||
@Override
|
||||
public int getHeight() { return mHeight; }
|
||||
public IntSize getSize() { return mBufferSize; }
|
||||
@Override
|
||||
public int getFormat() { return mFormat; }
|
||||
};
|
||||
|
@ -141,7 +136,6 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
layerController.notifyPanZoomControllerOfGeometryChange(false);
|
||||
}
|
||||
|
||||
geometryChanged();
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:Update", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
|
||||
}
|
||||
|
@ -209,7 +203,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
|
||||
public Bitmap getBitmap() {
|
||||
try {
|
||||
Bitmap b = Bitmap.createBitmap(mWidth, mHeight,
|
||||
Bitmap b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,
|
||||
CairoUtils.cairoFormatTobitmapConfig(mFormat));
|
||||
b.copyPixelsFromBuffer(mBuffer.asIntBuffer());
|
||||
return b;
|
||||
|
@ -241,9 +235,28 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
if (metrics.widthPixels != mScreenSize.width ||
|
||||
metrics.heightPixels != mScreenSize.height) {
|
||||
mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels);
|
||||
int maxSize = getLayerController().getView().getMaxTextureSize();
|
||||
|
||||
// XXX Introduce tiling to solve this?
|
||||
if (mScreenSize.width > maxSize || mScreenSize.height > maxSize)
|
||||
throw new RuntimeException("Screen size of " + mScreenSize + " larger than maximum texture size of " + maxSize);
|
||||
|
||||
// Round to next power of two until we use NPOT texture support
|
||||
mBufferSize = new IntSize(Math.min(maxSize, IntSize.nextPowerOfTwo(mScreenSize.width + LayerController.MIN_BUFFER.width)),
|
||||
Math.min(maxSize, IntSize.nextPowerOfTwo(mScreenSize.height + LayerController.MIN_BUFFER.height)));
|
||||
|
||||
// Free the old buffer first, if it exists
|
||||
if (mBuffer != null) {
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mBuffer = null;
|
||||
}
|
||||
|
||||
// * 2 because it's a 16-bit buffer (so 2 bytes per pixel).
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mBufferSize.getArea() * 2);
|
||||
|
||||
Log.i(LOGTAG, "Screen-size changed to " + mScreenSize);
|
||||
GeckoEvent event = new GeckoEvent(GeckoEvent.SIZE_CHANGED,
|
||||
LayerController.TILE_WIDTH, LayerController.TILE_HEIGHT,
|
||||
mBufferSize.width, mBufferSize.height,
|
||||
metrics.widthPixels, metrics.heightPixels);
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
}
|
||||
|
@ -289,7 +302,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
ViewportMetrics viewportMetrics =
|
||||
new ViewportMetrics(getLayerController().getViewportMetrics());
|
||||
|
||||
PointF viewportOffset = viewportMetrics.getOptimumViewportOffset();
|
||||
PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(mBufferSize);
|
||||
viewportMetrics.setViewportOffset(viewportOffset);
|
||||
viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
|
||||
|
||||
|
|
|
@ -62,10 +62,18 @@ public class IntSize {
|
|||
}
|
||||
}
|
||||
|
||||
public int getArea() {
|
||||
return width * height;
|
||||
}
|
||||
|
||||
public boolean equals(IntSize size) {
|
||||
return ((size.width == width) && (size.height == height));
|
||||
}
|
||||
|
||||
public boolean isPositive() {
|
||||
return (width > 0 && height > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return "(" + width + "," + height + ")"; }
|
||||
|
||||
|
@ -73,5 +81,23 @@ public class IntSize {
|
|||
return new IntSize((int)Math.round(width * factor),
|
||||
(int)Math.round(height * factor));
|
||||
}
|
||||
|
||||
/* Returns the power of two that is greater than or equal to value */
|
||||
public static int nextPowerOfTwo(int value) {
|
||||
// code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
|
||||
if (0 == value--) {
|
||||
return 1;
|
||||
}
|
||||
value = (value >> 1) | value;
|
||||
value = (value >> 2) | value;
|
||||
value = (value >> 4) | value;
|
||||
value = (value >> 8) | value;
|
||||
value = (value >> 16) | value;
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
public IntSize nextPowerOfTwo() {
|
||||
return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ public abstract class Layer {
|
|||
/** Subclasses override this function to draw the layer. */
|
||||
public abstract void draw(RenderContext context);
|
||||
|
||||
/** Subclasses override this function to provide access to the size of the layer. */
|
||||
public abstract IntSize getSize();
|
||||
|
||||
/** Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect. */
|
||||
protected RectF getBounds(RenderContext context, FloatSize size) {
|
||||
float scaleFactor = context.zoomFactor / mResolution;
|
||||
|
@ -168,20 +171,6 @@ public abstract class Layer {
|
|||
}
|
||||
}
|
||||
|
||||
/* Returns the power of two that is greater than or equal to value */
|
||||
protected static int nextPowerOfTwo(int value) {
|
||||
// code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
|
||||
if (0 == value--) {
|
||||
return 1;
|
||||
}
|
||||
value = (value >> 1) | value;
|
||||
value = (value >> 2) | value;
|
||||
value = (value >> 4) | value;
|
||||
value = (value >> 8) | value;
|
||||
value = (value >> 16) | value;
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
public static class RenderContext {
|
||||
public final RectF viewport;
|
||||
public final FloatSize pageSize;
|
||||
|
|
|
@ -85,9 +85,11 @@ public class LayerController {
|
|||
|
||||
private boolean mForceRedraw;
|
||||
|
||||
/* NB: These must be powers of two due to the OpenGL ES 1.x restriction on NPOT textures. */
|
||||
public static final int TILE_WIDTH = 1024;
|
||||
public static final int TILE_HEIGHT = 2048;
|
||||
/* The extra area on the sides of the page that we want to buffer to help with
|
||||
* smooth, asynchronous scrolling. Depending on a device's support for NPOT
|
||||
* textures, this may be rounded up to the nearest power of two.
|
||||
*/
|
||||
public static final IntSize MIN_BUFFER = new IntSize(512, 1024);
|
||||
|
||||
/* If the visible rect is within the danger zone (measured in pixels from each edge of a tile),
|
||||
* we start aggressively redrawing to minimize checkerboarding. */
|
||||
|
@ -293,8 +295,12 @@ public class LayerController {
|
|||
}
|
||||
|
||||
private RectF getTileRect() {
|
||||
if (mRootLayer == null)
|
||||
return new RectF();
|
||||
|
||||
float x = mRootLayer.getOrigin().x, y = mRootLayer.getOrigin().y;
|
||||
return new RectF(x, y, x + TILE_WIDTH, y + TILE_HEIGHT);
|
||||
IntSize layerSize = mRootLayer.getSize();
|
||||
return new RectF(x, y, x + layerSize.width, y + layerSize.height);
|
||||
}
|
||||
|
||||
public RectF restrictToPageSize(RectF aRect) {
|
||||
|
|
|
@ -90,6 +90,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
private final ScrollbarLayer mVertScrollLayer;
|
||||
private final FadeRunnable mFadeRunnable;
|
||||
private RenderContext mLastPageContext;
|
||||
private int mMaxTextureSize;
|
||||
|
||||
// Dropped frames display
|
||||
private int[] mFrameTimings;
|
||||
|
@ -122,12 +123,17 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
checkFrameRateMonitorEnabled();
|
||||
|
||||
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
gl.glClearDepthf(1.0f); /* FIXME: Is this needed? */
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH); /* FIXME: Is this needed? */
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
|
||||
int maxTextureSizeResult[] = new int[1];
|
||||
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
|
||||
mMaxTextureSize = maxTextureSizeResult[0];
|
||||
}
|
||||
|
||||
public int getMaxTextureSize() {
|
||||
return mMaxTextureSize;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -167,5 +167,9 @@ public class LayerView extends GLSurfaceView {
|
|||
return System.nanoTime() - mRenderTime;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaxTextureSize() {
|
||||
return mRenderer.getMaxTextureSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ public class ScrollbarLayer extends TileLayer {
|
|||
mVertical = vertical;
|
||||
mBuffer = buffer;
|
||||
|
||||
mBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
IntSize size = image.getSize();
|
||||
mBitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
}
|
||||
|
||||
|
@ -100,7 +101,7 @@ public class ScrollbarLayer extends TileLayer {
|
|||
public static ScrollbarLayer create(boolean vertical) {
|
||||
// just create an empty image for now, it will get drawn
|
||||
// on demand anyway
|
||||
int imageSize = nextPowerOfTwo(BAR_SIZE);
|
||||
int imageSize = IntSize.nextPowerOfTwo(BAR_SIZE);
|
||||
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(imageSize * imageSize * 4);
|
||||
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, CairoImage.FORMAT_ARGB32);
|
||||
return new ScrollbarLayer(image, vertical, buffer);
|
||||
|
|
|
@ -39,6 +39,7 @@ package org.mozilla.gecko.gfx;
|
|||
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLES20;
|
||||
import android.util.Log;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL11Ext;
|
||||
|
@ -58,27 +59,18 @@ public abstract class TileLayer extends Layer {
|
|||
private final ArrayList<Rect> mDirtyRects;
|
||||
private final CairoImage mImage;
|
||||
private final boolean mRepeat;
|
||||
private final IntSize mSize;
|
||||
private IntSize mSize;
|
||||
private int[] mTextureIDs;
|
||||
|
||||
public TileLayer(boolean repeat, CairoImage image) {
|
||||
mRepeat = repeat;
|
||||
mImage = image;
|
||||
mSize = new IntSize(image.getWidth(), image.getHeight());
|
||||
mSize = new IntSize(0, 0);
|
||||
mDirtyRects = new ArrayList<Rect>();
|
||||
|
||||
/*
|
||||
* Assert that the image has a power-of-two size. OpenGL ES < 2.0 doesn't support NPOT
|
||||
* textures and OpenGL ES doesn't seem to let us efficiently slice up a NPOT bitmap.
|
||||
*/
|
||||
int width = mImage.getWidth(), height = mImage.getHeight();
|
||||
if ((width & (width - 1)) != 0 || (height & (height - 1)) != 0) {
|
||||
throw new RuntimeException("TileLayer: NPOT images are unsupported (dimensions are " +
|
||||
width + "x" + height + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public IntSize getSize() { return mSize; }
|
||||
@Override
|
||||
public IntSize getSize() { return mImage.getSize(); }
|
||||
|
||||
protected boolean repeats() { return mRepeat; }
|
||||
protected int getTextureID() { return mTextureIDs[0]; }
|
||||
|
@ -101,13 +93,49 @@ public abstract class TileLayer extends Layer {
|
|||
}
|
||||
|
||||
public void invalidate() {
|
||||
invalidate(new Rect(0, 0, mSize.width, mSize.height));
|
||||
IntSize bufferSize = mImage.getSize();
|
||||
invalidate(new Rect(0, 0, bufferSize.width, bufferSize.height));
|
||||
}
|
||||
|
||||
private void validateTexture() {
|
||||
/* Calculate the ideal texture size. This must be a power of two if
|
||||
* the texture is repeated or OpenGL ES 2.0 isn't supported, as
|
||||
* OpenGL ES 2.0 is required for NPOT texture support (without
|
||||
* extensions), but doesn't support repeating NPOT textures.
|
||||
*
|
||||
* XXX Currently, we don't pick a GLES 2.0 context, so always round.
|
||||
*/
|
||||
IntSize bufferSize = mImage.getSize();
|
||||
IntSize textureSize = bufferSize;
|
||||
|
||||
textureSize = bufferSize.nextPowerOfTwo();
|
||||
|
||||
if (!textureSize.equals(mSize)) {
|
||||
mSize = textureSize;
|
||||
|
||||
// Delete the old texture
|
||||
if (mTextureIDs != null) {
|
||||
TextureReaper.get().add(mTextureIDs);
|
||||
mTextureIDs = null;
|
||||
|
||||
// XXX This won't be freed until the next frame is drawn, so we
|
||||
// temporarily have a larger-than-necessary memory requirement.
|
||||
// Is this what we want?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performUpdates(GL10 gl) {
|
||||
super.performUpdates(gl);
|
||||
|
||||
// Reallocate the texture if the size has changed
|
||||
validateTexture();
|
||||
|
||||
// Don't do any work if the image has an invalid size.
|
||||
if (!mImage.getSize().isPositive())
|
||||
return;
|
||||
|
||||
if (mTextureIDs == null) {
|
||||
uploadFullTexture(gl);
|
||||
} else {
|
||||
|
@ -119,43 +147,58 @@ public abstract class TileLayer extends Layer {
|
|||
}
|
||||
|
||||
private void uploadFullTexture(GL10 gl) {
|
||||
mTextureIDs = new int[1];
|
||||
gl.glGenTextures(mTextureIDs.length, mTextureIDs, 0);
|
||||
|
||||
int cairoFormat = mImage.getFormat();
|
||||
CairoGLInfo glInfo = new CairoGLInfo(cairoFormat);
|
||||
|
||||
bindAndSetGLParameters(gl);
|
||||
|
||||
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, mSize.height,
|
||||
0, glInfo.format, glInfo.type, mImage.getBuffer());
|
||||
IntSize bufferSize = mImage.getSize();
|
||||
uploadDirtyRect(gl, new Rect(0, 0, bufferSize.width, bufferSize.height));
|
||||
}
|
||||
|
||||
|
||||
private void uploadDirtyRect(GL10 gl, Rect dirtyRect) {
|
||||
if (mTextureIDs == null)
|
||||
throw new RuntimeException("uploadDirtyRect() called with null texture ID!");
|
||||
boolean newlyCreated = false;
|
||||
|
||||
if (mTextureIDs == null) {
|
||||
mTextureIDs = new int[1];
|
||||
gl.glGenTextures(mTextureIDs.length, mTextureIDs, 0);
|
||||
newlyCreated = true;
|
||||
}
|
||||
|
||||
IntSize bufferSize = mImage.getSize();
|
||||
Rect bufferRect = new Rect(0, 0, bufferSize.width, bufferSize.height);
|
||||
|
||||
int width = mSize.width;
|
||||
int cairoFormat = mImage.getFormat();
|
||||
CairoGLInfo glInfo = new CairoGLInfo(cairoFormat);
|
||||
|
||||
bindAndSetGLParameters(gl);
|
||||
|
||||
if (newlyCreated || dirtyRect.equals(bufferRect)) {
|
||||
if (mSize.equals(bufferSize)) {
|
||||
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, mSize.height,
|
||||
0, glInfo.format, glInfo.type, mImage.getBuffer());
|
||||
return;
|
||||
} else {
|
||||
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, mSize.height,
|
||||
0, glInfo.format, glInfo.type, null);
|
||||
gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, bufferSize.width, bufferSize.height,
|
||||
glInfo.format, glInfo.type, mImage.getBuffer());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Upload the changed rect. We have to widen to the full width of the texture
|
||||
* because we can't count on the device having support for GL_EXT_unpack_subimage,
|
||||
* and going line-by-line is too slow.
|
||||
*
|
||||
* XXX We should still use GL_EXT_unpack_subimage when available.
|
||||
*/
|
||||
Buffer viewBuffer = mImage.getBuffer().slice();
|
||||
int bpp = CairoUtils.bitsPerPixelForCairoFormat(cairoFormat) / 8;
|
||||
int position = dirtyRect.top * width * bpp;
|
||||
int position = dirtyRect.top * bufferSize.width * bpp;
|
||||
if (position > viewBuffer.limit()) {
|
||||
Log.e(LOGTAG, "### Position outside tile! " + dirtyRect.top);
|
||||
return;
|
||||
}
|
||||
|
||||
viewBuffer.position(position);
|
||||
gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, dirtyRect.top, width, dirtyRect.height(),
|
||||
gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, dirtyRect.top, bufferSize.width, dirtyRect.height(),
|
||||
glInfo.format, glInfo.type, viewBuffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ import android.graphics.Rect;
|
|||
import android.graphics.RectF;
|
||||
import org.mozilla.gecko.FloatUtils;
|
||||
import org.mozilla.gecko.gfx.FloatSize;
|
||||
import org.mozilla.gecko.gfx.IntSize;
|
||||
import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.RectUtils;
|
||||
import org.json.JSONException;
|
||||
|
@ -64,8 +65,7 @@ public class ViewportMetrics {
|
|||
private float mZoomFactor;
|
||||
|
||||
public ViewportMetrics() {
|
||||
mPageSize = new FloatSize(LayerController.TILE_WIDTH,
|
||||
LayerController.TILE_HEIGHT);
|
||||
mPageSize = new FloatSize(1, 1);
|
||||
mViewportRect = new RectF(0, 0, 1, 1);
|
||||
mViewportOffset = new PointF(0, 0);
|
||||
mZoomFactor = 1.0f;
|
||||
|
@ -96,13 +96,13 @@ public class ViewportMetrics {
|
|||
mZoomFactor = zoom;
|
||||
}
|
||||
|
||||
public PointF getOptimumViewportOffset() {
|
||||
public PointF getOptimumViewportOffset(IntSize displayportSize) {
|
||||
// XXX We currently always position the viewport in the centre of the
|
||||
// displayport, but we might want to optimise this during panning
|
||||
// to minimise checkerboarding.
|
||||
Point optimumOffset =
|
||||
new Point((int)Math.round((LayerController.TILE_WIDTH - mViewportRect.width()) / 2),
|
||||
(int)Math.round((LayerController.TILE_HEIGHT - mViewportRect.height()) / 2));
|
||||
new Point((int)Math.round((displayportSize.width - mViewportRect.width()) / 2),
|
||||
(int)Math.round((displayportSize.height - mViewportRect.height()) / 2));
|
||||
|
||||
/* XXX Until bug #524925 is fixed, changing the viewport origin will
|
||||
* probably cause things to be slower than just having a smaller usable
|
||||
|
|
|
@ -79,10 +79,6 @@ using mozilla::unused;
|
|||
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
// NB: Keep these in sync with LayerController.java in mobile/android/base and embedding/android/.
|
||||
#define TILE_WIDTH 1024
|
||||
#define TILE_HEIGHT 2048
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
|
@ -310,7 +306,7 @@ nsWindow::ConfigureChildren(const nsTArray<nsIWidget::Configuration>& config)
|
|||
void
|
||||
nsWindow::RedrawAll()
|
||||
{
|
||||
nsIntRect entireRect(0, 0, TILE_WIDTH, TILE_HEIGHT);
|
||||
nsIntRect entireRect(0, 0, gAndroidBounds.width, gAndroidBounds.height);
|
||||
AndroidGeckoEvent *event = new AndroidGeckoEvent(AndroidGeckoEvent::DRAW, entireRect);
|
||||
nsAppShell::gAppShell->PostEvent(event);
|
||||
}
|
||||
|
@ -1018,7 +1014,7 @@ nsWindow::DrawTo(gfxASurface *targetSurface, const nsIntRect &invalidRect)
|
|||
if (coveringChildIndex == -1) {
|
||||
nsPaintEvent event(true, NS_PAINT, this);
|
||||
|
||||
nsIntRect tileRect(0, 0, TILE_WIDTH, TILE_HEIGHT);
|
||||
nsIntRect tileRect(0, 0, gAndroidBounds.width, gAndroidBounds.height);
|
||||
event.region = boundsRect.Intersect(invalidRect).Intersect(tileRect);
|
||||
|
||||
switch (GetLayerManager(nsnull)->GetBackendType()) {
|
||||
|
@ -1112,7 +1108,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
|||
|
||||
unsigned char *bits = client.LockBufferBits();
|
||||
nsRefPtr<gfxImageSurface> targetSurface =
|
||||
new gfxImageSurface(bits, gfxIntSize(TILE_WIDTH, TILE_HEIGHT), TILE_WIDTH * 2,
|
||||
new gfxImageSurface(bits, gfxIntSize(gAndroidBounds.width, gAndroidBounds.height), gAndroidBounds.width * 2,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
if (targetSurface->CairoStatus()) {
|
||||
ALOG("### Failed to create a valid surface from the bitmap");
|
||||
|
|
Загрузка…
Ссылка в новой задаче