2
0
mirror of synced 2025-02-23 14:58:12 +00:00
mobile/geom/geom.go
Nigel Tao 42f0d17876 app: use one thread for both GL and other UI C code.
This change will break Darwin. I have only built and tested this on
desktop linux and Android linux. A follow-up CL will fix Darwin.

Currently, OpenGL gets its own thread, and UI C code (e.g. the Android
event loop, or the X11 event loop) gets its own thread. This relies on
multiple system-provided UI-related C libraries working nicely together,
even when running on different threads. Keeping all the C code on the
one thread seems more sound.

As side-effects:
  - In package app/debug, DrawFPS now takes an explicit Config.
  - In package app, some callbacks now take an explicit Config.
  - In package exp/sprite, Render now takes an explicit Config.
  - In package event, there are new events (Config, Draw, Lifecycle),
    and an event filter mechanism to replace multiple app Callbacks.
  - In package geom, the deprecated Width, Height and PixelsPerPt global
    variables were removed in favor of an event.Config that is
    explicitly passed around (and does not require mutex-locking).
    Converting a geom.Pt to pixels now requires passing a pixelsPerPt.
  - In package gl, the Do, Start and Stop functions are removed, as well
    as the need to call Start in its own goroutine. There is no longer a
    separate GL thread. Instead, package app explicitly performs any GL
    work (gl.DoWork) when some is available (gl.WorkAvailable).
  - In package gl/glutil, Image.Draw now takes an explicit Config.

Callbacks are no longer executed on 'the UI thread'.

Changing the app programming model from callbacks to events (since a
channel of events works with select) will be a follow-up change.

Change-Id: Id9865cd9ee1c45a98c613e9021a63c17226a64b1
Reviewed-on: https://go-review.googlesource.com/11351
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-26 07:43:17 +00:00

103 lines
3.7 KiB
Go

// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package geom defines a two-dimensional coordinate system.
The coordinate system is based on an left-handed Cartesian plane.
That is, X increases to the right and Y increases down. For (x,y),
(0,0) → (1,0)
↓ ↘
(0,1) (1,1)
The display window places the origin (0, 0) in the upper-left corner of
the screen. Positions on the plane are measured in typographic points,
1/72 of an inch, which is represented by the Pt type.
Any interface that draws to the screen using types from the geom package
scales the number of pixels to maintain a Pt as 1/72 of an inch.
*/
package geom // import "golang.org/x/mobile/geom"
/*
Notes on the various underlying coordinate systems.
Both Android and iOS (UIKit) use upper-left-origin coordinate systems
with for events, however they have different units.
UIKit measures distance in points. A point is a single-pixel on a
pre-Retina display. UIKit maintains a scale factor that to turn points
into pixels. On current retina devices, the scale factor is 2.0.
A UIKit point does not correspond to a fixed physical distance, as the
iPhone has a 163 DPI/PPI (326 PPI retina) display, and the iPad has a
132 PPI (264 retina) display. Points are 32-bit floats.
Even though point is the official UIKit term, they are commonly called
pixels. Indeed, the units were equivalent until the retina display was
introduced.
N.b. as a UIKit point is unrelated to a typographic point, it is not
related to this packages's Pt and Point types.
More details about iOS drawing:
https://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/GraphicsDrawingOverview/GraphicsDrawingOverview.html
Android uses pixels. Sub-pixel precision is possible, so pixels are
represented as 32-bit floats. The ACONFIGURATION_DENSITY enum provides
the screen DPI/PPI, which varies frequently between devices.
It would be tempting to adopt the pixel, given the clear pixel/DPI split
in the core android events API. However, the plot thickens:
http://developer.android.com/training/multiscreen/screendensities.html
Android promotes the notion of a density-independent pixel in many of
their interfaces, often prefixed by "dp". 1dp is a real physical length,
as "independent" means it is assumed to be 1/160th of an inch and is
adjusted for the current screen.
In addition, android has a scale-indepdendent pixel used for expressing
a user's preferred text size. The user text size preference is a useful
notion not yet expressed in the geom package.
For the sake of clarity when working across platforms, the geom package
tries to put distance between it and the word pixel.
*/
import "fmt"
// Pt is a length.
//
// The unit Pt is a typographical point, 1/72 of an inch (0.3527 mm).
//
// It can be be converted to a length in current device pixels by
// multiplying with PixelsPerPt after app initialization is complete.
type Pt float32
// Px converts the length to current device pixels.
func (p Pt) Px(pixelsPerPt float32) float32 { return float32(p) * pixelsPerPt }
// String returns a string representation of p like "3.2pt".
func (p Pt) String() string { return fmt.Sprintf("%.2fpt", p) }
// Point is a point in a two-dimensional plane.
type Point struct {
X, Y Pt
}
// String returns a string representation of p like "(1.2,3.4)".
func (p Point) String() string { return fmt.Sprintf("(%.2f,%.2f)", p.X, p.Y) }
// A Rectangle is region of points.
// The top-left point is Min, and the bottom-right point is Max.
type Rectangle struct {
Min, Max Point
}
// String returns a string representation of r like "(3,4)-(6,5)".
func (r Rectangle) String() string { return r.Min.String() + "-" + r.Max.String() }