LibreOffice Module android (master) 1
ComposedTileLayer.java
Go to the documentation of this file.
1package org.mozilla.gecko.gfx;
2
3import android.content.ComponentCallbacks2;
4import android.content.Context;
5import android.content.res.Configuration;
6import android.graphics.RectF;
7import android.graphics.Region;
8import android.util.Log;
9
13
14import java.util.ArrayList;
15import java.util.Iterator;
16import java.util.List;
17import java.util.concurrent.locks.Lock;
18import java.util.concurrent.locks.ReadWriteLock;
19import java.util.concurrent.locks.ReentrantReadWriteLock;
20
21public abstract class ComposedTileLayer extends Layer implements ComponentCallbacks2 {
22 private static final String LOGTAG = ComposedTileLayer.class.getSimpleName();
23
24 protected final List<SubTile> tiles = new ArrayList<SubTile>();
25
26 protected final IntSize tileSize;
27 private final ReadWriteLock tilesReadWriteLock = new ReentrantReadWriteLock();
28 private final Lock tilesReadLock = tilesReadWriteLock.readLock();
29 private final Lock tilesWriteLock = tilesReadWriteLock.writeLock();
30
31 protected RectF currentViewport = new RectF();
32 protected float currentZoom = 1.0f;
33 protected RectF currentPageRect = new RectF();
34
35 private long reevaluationNanoTime = 0;
36
37 public ComposedTileLayer(Context context) {
38 context.registerComponentCallbacks(this);
39 this.tileSize = new IntSize(256, 256);
40 }
41
42 protected static RectF roundToTileSize(RectF input, IntSize tileSize) {
43 float minX = ((int) (input.left / tileSize.width)) * tileSize.width;
44 float minY = ((int) (input.top / tileSize.height)) * tileSize.height;
45 float maxX = ((int) (input.right / tileSize.width) + 1) * tileSize.width;
46 float maxY = ((int) (input.bottom / tileSize.height) + 1) * tileSize.height;
47 return new RectF(minX, minY, maxX, maxY);
48 }
49
50 protected static RectF inflate(RectF rect, IntSize inflateSize) {
51 RectF newRect = new RectF(rect);
52 newRect.left -= inflateSize.width;
53 newRect.left = newRect.left < 0.0f ? 0.0f : newRect.left;
54
55 newRect.top -= inflateSize.height;
56 newRect.top = newRect.top < 0.0f ? 0.0f : newRect.top;
57
58 newRect.right += inflateSize.width;
59 newRect.bottom += inflateSize.height;
60
61 return newRect;
62 }
63
64 protected static RectF normalizeRect(RectF rect, float sourceFactor, float targetFactor) {
65 return new RectF(
66 (rect.left / sourceFactor) * targetFactor,
67 (rect.top / sourceFactor) * targetFactor,
68 (rect.right / sourceFactor) * targetFactor,
69 (rect.bottom / sourceFactor) * targetFactor);
70 }
71
72 public void invalidate() {
73 tilesReadLock.lock();
74 for (SubTile tile : tiles) {
75 tile.invalidate();
76 }
77 tilesReadLock.unlock();
78 }
79
80 @Override
81 public void beginTransaction() {
82 super.beginTransaction();
83 tilesReadLock.lock();
84 for (SubTile tile : tiles) {
85 tile.beginTransaction();
86 }
87 tilesReadLock.unlock();
88 }
89
90 @Override
91 public void endTransaction() {
92 tilesReadLock.lock();
93 for (SubTile tile : tiles) {
94 tile.endTransaction();
95 }
96 tilesReadLock.unlock();
97 super.endTransaction();
98 }
99
100 @Override
101 public void draw(RenderContext context) {
102 tilesReadLock.lock();
103 for (SubTile tile : tiles) {
104 if (RectF.intersects(tile.getBounds(context), context.viewport)) {
105 tile.draw(context);
106 }
107 }
108 tilesReadLock.unlock();
109 }
110
111 @Override
112 protected void performUpdates(RenderContext context) {
113 super.performUpdates(context);
114
115 tilesReadLock.lock();
116 for (SubTile tile : tiles) {
117 tile.beginTransaction();
118 tile.refreshTileMetrics();
119 tile.endTransaction();
120 tile.performUpdates(context);
121 }
122 tilesReadLock.unlock();
123 }
124
125 @Override
126 public Region getValidRegion(RenderContext context) {
127 Region validRegion = new Region();
128 tilesReadLock.lock();
129 for (SubTile tile : tiles) {
130 validRegion.op(tile.getValidRegion(context), Region.Op.UNION);
131 }
132 tilesReadLock.unlock();
133 return validRegion;
134 }
135
136 @Override
137 public void setResolution(float newResolution) {
138 super.setResolution(newResolution);
139 tilesReadLock.lock();
140 for (SubTile tile : tiles) {
141 tile.setResolution(newResolution);
142 }
143 tilesReadLock.unlock();
144 }
145
146 public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics, DisplayPortMetrics mDisplayPort) {
147 RectF newViewPort = getViewPort(viewportMetrics);
148 float newZoom = getZoom(viewportMetrics);
149
150 // When
151 if (newZoom <= 0.0 || Float.isNaN(newZoom)) {
152 return;
153 }
154
155 if (currentViewport.equals(newViewPort) && FloatUtils.fuzzyEquals(currentZoom, newZoom)) {
156 return;
157 }
158
159 long currentReevaluationNanoTime = System.nanoTime();
160 if ((currentReevaluationNanoTime - reevaluationNanoTime) < 25 * 1000000) {
161 return;
162 }
163
164 reevaluationNanoTime = currentReevaluationNanoTime;
165
166 currentViewport = newViewPort;
167 currentZoom = newZoom;
168 currentPageRect = viewportMetrics.getPageRect();
169
171 }
172
173 protected abstract RectF getViewPort(ImmutableViewportMetrics viewportMetrics);
174
175 protected abstract float getZoom(ImmutableViewportMetrics viewportMetrics);
176
177 protected abstract int getTilePriority();
178
179 private boolean containsTilesMatching(float x, float y, float currentZoom) {
180 tilesReadLock.lock();
181 try {
182 for (SubTile tile : tiles) {
183 if (tile.id.x == x && tile.id.y == y && tile.id.zoom == currentZoom) {
184 return true;
185 }
186 }
187 return false;
188 } finally {
189 tilesReadLock.unlock();
190 }
191 }
192
193 public void addNewTiles(List<SubTile> newTiles) {
194 for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) {
195 if (y > currentPageRect.height()) {
196 continue;
197 }
198 for (float x = currentViewport.left; x < currentViewport.right; x += tileSize.width) {
199 if (x > currentPageRect.width()) {
200 continue;
201 }
203 TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
204 SubTile tile = createNewTile(tileId);
205 newTiles.add(tile);
206 }
207 }
208 }
209 }
210
211 public void clearMarkedTiles() {
212 tilesWriteLock.lock();
213 Iterator<SubTile> iterator = tiles.iterator();
214 while (iterator.hasNext()) {
215 SubTile tile = iterator.next();
216 if (tile.markedForRemoval) {
217 tile.destroy();
218 iterator.remove();
219 }
220 }
221 tilesWriteLock.unlock();
222 }
223
224 public void markTiles() {
225 tilesReadLock.lock();
226 for (SubTile tile : tiles) {
227 if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
228 RectF tileRect = tile.id.getRectF();
229 if (!RectF.intersects(currentViewport, tileRect)) {
230 tile.markForRemoval();
231 }
232 } else {
233 tile.markForRemoval();
234 }
235 }
236 tilesReadLock.unlock();
237 }
238
239 public void clearAndReset() {
240 tilesWriteLock.lock();
241 tiles.clear();
242 tilesWriteLock.unlock();
243 currentViewport = new RectF();
244 }
245
247 SubTile tile = new SubTile(tileId);
248 tile.beginTransaction();
249 tilesWriteLock.lock();
250 tiles.add(tile);
251 tilesWriteLock.unlock();
252 return tile;
253 }
254
255 public boolean isStillValid(TileIdentifier tileId) {
256 return RectF.intersects(currentViewport, tileId.getRectF()) || currentViewport.contains(tileId.getRectF());
257 }
258
262 public void invalidateTiles(List<SubTile> tilesToInvalidate, RectF cssRect) {
263 RectF zoomedRect = RectUtils.scale(cssRect, currentZoom);
264 tilesReadLock.lock();
265 for (SubTile tile : tiles) {
266 if (!tile.markedForRemoval && RectF.intersects(zoomedRect, tile.id.getRectF())) {
267 tilesToInvalidate.add(tile);
268 }
269 }
270 tilesReadLock.unlock();
271 }
272
273 @Override
274 public void onConfigurationChanged(Configuration newConfig) {
275 }
276
277 @Override
278 public void onLowMemory() {
279 Log.i(LOGTAG, "onLowMemory");
280 }
281
282 @Override
283 public void onTrimMemory(int level) {
284 if (level >= 15 /*TRIM_MEMORY_RUNNING_CRITICAL*/) {
285 Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_CRITICAL");
286 } else if (level >= 10 /*TRIM_MEMORY_RUNNING_LOW*/) {
287 Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_LOW");
288 }
289 }
290}
Common static LOKit functions, functions to send events.
Definition: LOKitShell.java:26
static void sendTileReevaluationRequest(ComposedTileLayer composedTileLayer)
Send tile reevaluation to LOKitThread.
Identifies the tile by its position (x and y coordinate on the document), zoom and tile size (current...
RectF getRectF()
Returns a rectangle of the tiles position in scaled coordinates.
void beginTransaction()
Call this before modifying the layer.
static RectF roundToTileSize(RectF input, IntSize tileSize)
void reevaluateTiles(ImmutableViewportMetrics viewportMetrics, DisplayPortMetrics mDisplayPort)
boolean isStillValid(TileIdentifier tileId)
boolean containsTilesMatching(float x, float y, float currentZoom)
static RectF normalizeRect(RectF rect, float sourceFactor, float targetFactor)
void setResolution(float newResolution)
Sets the layer resolution.
void onConfigurationChanged(Configuration newConfig)
void addNewTiles(List< SubTile > newTiles)
Region getValidRegion(RenderContext context)
Returns the region of the layer that is considered valid.
void endTransaction()
Call this when you're done modifying the layer.
void draw(RenderContext context)
Subclasses override this function to draw the layer.
void invalidateTiles(List< SubTile > tilesToInvalidate, RectF cssRect)
Invalidate tiles which intersect the input rect.
SubTile createNewTile(TileIdentifier tileId)
static RectF inflate(RectF rect, IntSize inflateSize)
abstract float getZoom(ImmutableViewportMetrics viewportMetrics)
abstract RectF getViewPort(ImmutableViewportMetrics viewportMetrics)
void performUpdates(RenderContext context)
Subclasses may override this method to perform custom layer updates.
ImmutableViewportMetrics are used to store the viewport metrics in way that we can access a version o...
void beginTransaction()
Call this before modifying the layer.
Definition: Layer.java:87
static RectF scale(RectF rect, float scale)
Definition: RectUtils.java:44
static boolean fuzzyEquals(float a, float b)
Definition: FloatUtils.java:13
float y
float x
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int