mobile/android/base/gfx/SingleTileLayer.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.gfx;
     8 import android.graphics.Rect;
     9 import android.graphics.RectF;
    10 import android.graphics.Region;
    11 import android.graphics.RegionIterator;
    12 import android.opengl.GLES20;
    14 import java.nio.FloatBuffer;
    16 /**
    17  * Encapsulates the logic needed to draw a single textured tile.
    18  *
    19  * TODO: Repeating textures really should be their own type of layer.
    20  */
    21 public class SingleTileLayer extends TileLayer {
    22     private static final String LOGTAG = "GeckoSingleTileLayer";
    24     private Rect mMask;
    26     // To avoid excessive GC, declare some objects here that would otherwise
    27     // be created and destroyed frequently during draw().
    28     private final RectF mBounds;
    29     private final RectF mTextureBounds;
    30     private final RectF mViewport;
    31     private final Rect mIntBounds;
    32     private final Rect mSubRect;
    33     private final RectF mSubRectF;
    34     private final Region mMaskedBounds;
    35     private final Rect mCropRect;
    36     private final RectF mObjRectF;
    37     private final float[] mCoords;
    39     public SingleTileLayer(CairoImage image) {
    40         this(false, image);
    41     }
    43     public SingleTileLayer(boolean repeat, CairoImage image) {
    44         this(image, repeat ? TileLayer.PaintMode.REPEAT : TileLayer.PaintMode.NORMAL);
    45     }
    47     public SingleTileLayer(CairoImage image, TileLayer.PaintMode paintMode) {
    48         super(image, paintMode);
    50         mBounds = new RectF();
    51         mTextureBounds = new RectF();
    52         mViewport = new RectF();
    53         mIntBounds = new Rect();
    54         mSubRect = new Rect();
    55         mSubRectF = new RectF();
    56         mMaskedBounds = new Region();
    57         mCropRect = new Rect();
    58         mObjRectF = new RectF();
    59         mCoords = new float[20];
    60     }
    62     /**
    63      * Set an area to mask out when rendering.
    64      */
    65     public void setMask(Rect aMaskRect) {
    66         mMask = aMaskRect;
    67     }
    69     @Override
    70     public void draw(RenderContext context) {
    71         // mTextureIDs may be null here during startup if Layer.java's draw method
    72         // failed to acquire the transaction lock and call performUpdates.
    73         if (!initialized())
    74             return;
    76         mViewport.set(context.viewport);
    78         if (repeats()) {
    79             // If we're repeating, we want to adjust the texture bounds so that
    80             // the texture repeats the correct number of times when drawn at
    81             // the size of the viewport.
    82             mBounds.set(getBounds(context));
    83             mTextureBounds.set(0.0f, 0.0f, mBounds.width(), mBounds.height());
    84             mBounds.set(0.0f, 0.0f, mViewport.width(), mViewport.height());
    85         } else if (stretches()) {
    86             // If we're stretching, we just want the bounds and texture bounds
    87             // to fit to the page.
    88             mBounds.set(context.pageRect);
    89             mTextureBounds.set(mBounds);
    90         } else {
    91             mBounds.set(getBounds(context));
    92             mTextureBounds.set(mBounds);
    93         }
    95         mBounds.roundOut(mIntBounds);
    96         mMaskedBounds.set(mIntBounds);
    97         if (mMask != null) {
    98             mMaskedBounds.op(mMask, Region.Op.DIFFERENCE);
    99             if (mMaskedBounds.isEmpty())
   100                 return;
   101         }
   103         // XXX Possible optimisation here, form this array so we can draw it in
   104         //     a single call.
   105         RegionIterator i = new RegionIterator(mMaskedBounds);
   106         while (i.next(mSubRect)) {
   107             // Compensate for rounding errors at the edge of the tile caused by
   108             // the roundOut above
   109             mSubRectF.set(Math.max(mBounds.left, (float)mSubRect.left),
   110                           Math.max(mBounds.top, (float)mSubRect.top),
   111                           Math.min(mBounds.right, (float)mSubRect.right),
   112                           Math.min(mBounds.bottom, (float)mSubRect.bottom));
   114             // This is the left/top/right/bottom of the rect, relative to the
   115             // bottom-left of the layer, to use for texture coordinates.
   116             mCropRect.set(Math.round(mSubRectF.left - mBounds.left),
   117                           Math.round(mBounds.bottom - mSubRectF.top),
   118                           Math.round(mSubRectF.right - mBounds.left),
   119                           Math.round(mBounds.bottom - mSubRectF.bottom));
   121             mObjRectF.set(mSubRectF.left - mViewport.left,
   122                           mViewport.bottom - mSubRectF.bottom,
   123                           mSubRectF.right - mViewport.left,
   124                           mViewport.bottom - mSubRectF.top);
   126             fillRectCoordBuffer(mCoords, mObjRectF, mViewport.width(), mViewport.height(),
   127                                 mCropRect, mTextureBounds.width(), mTextureBounds.height());
   129             FloatBuffer coordBuffer = context.coordBuffer;
   130             int positionHandle = context.positionHandle;
   131             int textureHandle = context.textureHandle;
   133             GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
   134             GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
   136             // Make sure we are at position zero in the buffer
   137             coordBuffer.position(0);
   138             coordBuffer.put(mCoords);
   140             // Unbind any the current array buffer so we can use client side buffers
   141             GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
   143             // Vertex coordinates are x,y,z starting at position 0 into the buffer.
   144             coordBuffer.position(0);
   145             GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
   147             // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
   148             coordBuffer.position(3);
   149             GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
   150             GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
   151         }
   152     }
   153 }

mercurial