6package org.mozilla.gecko.gfx;
8import android.graphics.PointF;
9import android.graphics.RectF;
10import android.util.Log;
12import org.json.JSONArray;
19final class DisplayPortCalculator {
20 private static final String LOGTAG = DisplayPortCalculator.class.getSimpleName();
21 private static final PointF ZERO_VELOCITY =
new PointF(0, 0);
24 private static final int TILE_SIZE = 256;
26 private static final String PREF_DISPLAYPORT_STRATEGY =
"gfx.displayport.strategy";
27 private static final String PREF_DISPLAYPORT_FM_MULTIPLIER =
"gfx.displayport.strategy_fm.multiplier";
28 private static final String PREF_DISPLAYPORT_FM_DANGER_X =
"gfx.displayport.strategy_fm.danger_x";
29 private static final String PREF_DISPLAYPORT_FM_DANGER_Y =
"gfx.displayport.strategy_fm.danger_y";
30 private static final String PREF_DISPLAYPORT_VB_MULTIPLIER =
"gfx.displayport.strategy_vb.multiplier";
31 private static final String PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD =
"gfx.displayport.strategy_vb.threshold";
32 private static final String PREF_DISPLAYPORT_VB_REVERSE_BUFFER =
"gfx.displayport.strategy_vb.reverse_buffer";
33 private static final String PREF_DISPLAYPORT_VB_DANGER_X_BASE =
"gfx.displayport.strategy_vb.danger_x_base";
34 private static final String PREF_DISPLAYPORT_VB_DANGER_Y_BASE =
"gfx.displayport.strategy_vb.danger_y_base";
35 private static final String PREF_DISPLAYPORT_VB_DANGER_X_INCR =
"gfx.displayport.strategy_vb.danger_x_incr";
36 private static final String PREF_DISPLAYPORT_VB_DANGER_Y_INCR =
"gfx.displayport.strategy_vb.danger_y_incr";
37 private static final String PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD =
"gfx.displayport.strategy_pb.threshold";
39 private DisplayPortStrategy sStrategy;
40 private final LibreOfficeMainActivity mMainActivity;
42 DisplayPortCalculator(LibreOfficeMainActivity context) {
43 this.mMainActivity = context;
44 sStrategy =
new VelocityBiasStrategy(mMainActivity,
null);
47 DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
48 return sStrategy.calculate(metrics, (velocity ==
null ? ZERO_VELOCITY : velocity));
51 boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
52 if (displayPort ==
null) {
55 return sStrategy.aboutToCheckerboard(metrics, (velocity ==
null ? ZERO_VELOCITY : velocity), displayPort);
58 boolean drawTimeUpdate(
long millis,
int pixels) {
59 return sStrategy.drawTimeUpdate(millis, pixels);
62 void resetPageState() {
63 sStrategy.resetPageState();
66 static void addPrefNames(JSONArray prefs) {
67 prefs.put(PREF_DISPLAYPORT_STRATEGY);
68 prefs.put(PREF_DISPLAYPORT_FM_MULTIPLIER);
69 prefs.put(PREF_DISPLAYPORT_FM_DANGER_X);
70 prefs.put(PREF_DISPLAYPORT_FM_DANGER_Y);
71 prefs.put(PREF_DISPLAYPORT_VB_MULTIPLIER);
72 prefs.put(PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD);
73 prefs.put(PREF_DISPLAYPORT_VB_REVERSE_BUFFER);
74 prefs.put(PREF_DISPLAYPORT_VB_DANGER_X_BASE);
75 prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_BASE);
76 prefs.put(PREF_DISPLAYPORT_VB_DANGER_X_INCR);
77 prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_INCR);
78 prefs.put(PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD);
86 boolean setStrategy(Map<String, Integer> prefs) {
87 Integer strategy = prefs.get(PREF_DISPLAYPORT_STRATEGY);
88 if (strategy ==
null) {
94 sStrategy =
new FixedMarginStrategy(prefs);
97 sStrategy =
new VelocityBiasStrategy(mMainActivity, prefs);
100 sStrategy =
new DynamicResolutionStrategy(mMainActivity, prefs);
103 sStrategy =
new NoMarginStrategy(prefs);
106 sStrategy =
new PredictionBiasStrategy(mMainActivity, prefs);
109 Log.e(LOGTAG,
"Invalid strategy index specified");
112 Log.i(LOGTAG,
"Set strategy " + sStrategy.toString());
116 private static float getFloatPref(Map<String, Integer> prefs, String prefName,
int defaultValue) {
117 Integer value = (prefs ==
null ? null : prefs.get(prefName));
118 return (
float)(
value ==
null ||
value < 0 ? defaultValue :
value) / 1000f;
143 float extraUsableHeight = (float)
Math.floor(((width - usableWidth) * height) / usableWidth);
144 float usableHeight =
Math.min(height + extraUsableHeight, metrics.
getPageHeight());
145 if (usableHeight < height && usableWidth == width) {
147 float extraUsableWidth = (float)
Math.floor(((height - usableHeight) * width) / usableHeight);
150 return new FloatSize(usableWidth, usableHeight);
158 private static RectF expandByDangerZone(RectF rect,
float dangerZoneXMultiplier,
float dangerZoneYMultiplier, ImmutableViewportMetrics metrics) {
160 float dangerZoneX = metrics.getWidth() * dangerZoneXMultiplier;
161 float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier;
162 rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY);
164 return clampToPageBounds(rect, metrics);
173 private static DisplayPortMetrics getTileAlignedDisplayPortMetrics(RectF margins,
float zoom, ImmutableViewportMetrics metrics) {
174 float left = metrics.viewportRectLeft - margins.left;
175 float top = metrics.viewportRectTop - margins.top;
176 float right = metrics.viewportRectRight + margins.right;
177 float bottom = metrics.viewportRectBottom + margins.bottom;
178 left = (float)
Math.max(metrics.pageRectLeft, TILE_SIZE *
Math.floor(left / TILE_SIZE));
179 top = (float)
Math.max(metrics.pageRectTop, TILE_SIZE *
Math.floor(top / TILE_SIZE));
180 right = (float)
Math.min(metrics.pageRectRight, TILE_SIZE *
Math.ceil(right / TILE_SIZE));
181 bottom = (float)
Math.min(metrics.pageRectBottom, TILE_SIZE *
Math.ceil(bottom / TILE_SIZE));
182 return new DisplayPortMetrics(left, top, right, bottom, zoom);
191 private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) {
195 float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left);
196 float rightOverflow = (metrics.viewportRectRight + margins.right) - metrics.pageRectRight;
197 float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top);
198 float bottomOverflow = (metrics.viewportRectBottom + margins.bottom) - metrics.pageRectBottom;
201 if (leftOverflow > 0) {
202 margins.left -= leftOverflow;
203 margins.right += leftOverflow;
204 }
else if (rightOverflow > 0) {
205 margins.right -= rightOverflow;
206 margins.left += rightOverflow;
208 if (topOverflow > 0) {
209 margins.top -= topOverflow;
210 margins.bottom += topOverflow;
211 }
else if (bottomOverflow > 0) {
212 margins.bottom -= bottomOverflow;
213 margins.top += bottomOverflow;
221 private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) {
222 if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop;
223 if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft;
224 if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight;
225 if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom;
251 return "NoMarginStrategy";
274 SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_MULTIPLIER, 2000);
287 FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
288 float horizontalBuffer = usableSize.
width - metrics.
getWidth();
296 RectF margins =
new RectF();
297 margins.left = horizontalBuffer / 2.0f;
298 margins.right = horizontalBuffer - margins.left;
299 margins.top = verticalBuffer / 2.0f;
300 margins.bottom = verticalBuffer - margins.top;
301 margins = shiftMarginsForPageBounds(margins, metrics);
303 return getTileAlignedDisplayPortMetrics(margins, metrics.
zoomFactor, metrics);
311 return !displayPort.
contains(adjustedViewport);
347 SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_MULTIPLIER, 2000);
349 REVERSE_BUFFER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_REVERSE_BUFFER, 200);
365 RectF margins =
new RectF();
372 margins.left = xAmount / 2.0f;
374 margins.right = xAmount - margins.left;
381 margins.top = yAmount / 2.0f;
383 margins.bottom = yAmount - margins.top;
397 displayPortWidth = metrics.
getWidth();
404 float horizontalBuffer = displayPortWidth - metrics.
getWidth();
405 float verticalBuffer = displayPortHeight - metrics.
getHeight();
410 margins = shiftMarginsForPageBounds(margins, metrics);
412 return getTileAlignedDisplayPortMetrics(margins, metrics.
zoomFactor, metrics);
427 dangerMargins = shiftMarginsForPageBounds(dangerMargins, metrics);
431 RectF adjustedViewport =
new RectF(
436 return !displayPort.
contains(adjustedViewport);
522 FloatSize reshapedSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
527 float velocityFactor =
Math.max(
Math.abs(velocity.x) / displayPortWidth,
528 Math.abs(velocity.y) / displayPortHeight);
531 displayPortWidth += (displayPortWidth * velocityFactor);
532 displayPortHeight += (displayPortHeight * velocityFactor);
545 FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
546 float horizontalBuffer = usableSize.
width - metrics.
getWidth();
554 RectF margins =
new RectF();
556 margins.right = horizontalBuffer - margins.left;
558 margins.bottom = verticalBuffer - margins.top;
562 margins = shiftMarginsForPageBounds(margins, metrics);
575 float displayResolution = metrics.
zoomFactor *
Math.min(1.0f, scaleFactor);
595 return amount / 2.0f;
622 if (velocity.length() > 0) {
623 if (velocity.x < 0) {
625 }
else if (velocity.x > 0) {
629 if (velocity.y < 0) {
631 }
else if (velocity.y > 0) {
639 return !displayPort.
contains(predictedViewport);
644 return "DynamicResolutionStrategy";
677 RectF margins =
new RectF(width, height, width, height);
678 return getTileAlignedDisplayPortMetrics(margins, metrics.
zoomFactor, metrics);
689 float pixelsToDraw = (width +
Math.abs(maxDx - minDx)) * (height +
Math.abs(maxDy - minDy));
698 RectF margins =
new RectF(
699 -
Math.min(minDx, maxDx),
700 -
Math.min(minDy, maxDy),
701 Math.max(minDx, maxDx),
702 Math.max(minDy, maxDy));
703 return getTileAlignedDisplayPortMetrics(margins, metrics.
zoomFactor, metrics);
721 predictedViewport.left += maxDx;
722 predictedViewport.top += maxDy;
723 predictedViewport.right += maxDx;
724 predictedViewport.bottom += maxDy;
726 predictedViewport = clampToPageBounds(predictedViewport, metrics);
727 return !displayPort.
contains(predictedViewport);
733 float normalizedTime = (float)
mPixelArea * (
float)millis / (float)pixels;
734 int normalizedFrames = (
int)
Math.ceil(normalizedTime * 60f / 1000f);
Common static LOKit functions, functions to send events.
static float getDpi(Context context)
Main activity of the LibreOffice App.
void resetPageState()
Reset any page-specific state stored, as the page being displayed has changed.
abstract DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
abstract boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
boolean drawTimeUpdate(long millis, int pixels)
Notify the strategy of a new recorded draw time.
This class implements the variation where we draw more of the page at low resolution while panning.
final float VELOCITY_EXPANSION_THRESHOLD
static final float PREDICTION_VELOCITY_MULTIPLIER
boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
static final float FAST_SPLIT_FACTOR
float splitBufferByVelocity(float amount, float velocity)
Split the given buffer amount into two based on the velocity.
static final float SIZE_MULTIPLIER
DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
final float VELOCITY_FAST_THRESHOLD
static final float DANGER_ZONE_MULTIPLIER
static final float VELOCITY_MULTIPLIER
static final float SLOW_SPLIT_FACTOR
This class implements the variation where we use a fixed-size margin on the display port.
DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
final float SIZE_MULTIPLIER
boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
final float DANGER_ZONE_Y_MULTIPLIER
final float DANGER_ZONE_X_MULTIPLIER
This class implements the variation where we basically don't bother with a display port.
boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
This class implements the variation where we use the draw time to predict where we will be when a dra...
DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
void resetPageState()
Reset any page-specific state stored, as the page being displayed has changed.
boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
boolean drawTimeUpdate(long millis, int pixels)
Notify the strategy of a new recorded draw time.
static float VELOCITY_THRESHOLD
This class implements the variation with a small fixed-size margin with velocity bias.
boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort)
Returns true if a checkerboard is about to be visible and we should not throttle drawing.
final float REVERSE_BUFFER
final float DANGER_ZONE_INCR_X_MULTIPLIER
final float DANGER_ZONE_INCR_Y_MULTIPLIER
DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity)
Calculates a displayport given a viewport and panning velocity.
final float VELOCITY_THRESHOLD
RectF velocityBiasedMargins(float xAmount, float yAmount, PointF velocity)
Split the given amounts into margins based on the VELOCITY_THRESHOLD and REVERSE_BUFFER values.
final float DANGER_ZONE_BASE_Y_MULTIPLIER
final float SIZE_MULTIPLIER
final float DANGER_ZONE_BASE_X_MULTIPLIER
boolean contains(RectF rect)
ImmutableViewportMetrics are used to store the viewport metrics in way that we can access a version o...
final float viewportRectRight
final float viewportRectLeft
final float viewportRectBottom
final float viewportRectTop
static boolean fuzzyEquals(float a, float b)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int