mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
7ad45c0d65
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1186934 followup needed to clear bustage
|
||||
Bug 1082598 - updating Skia
|
||||
|
@ -352,6 +352,7 @@ ${EndIf}
|
||||
${If} ${Errors}
|
||||
WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}\OpenWithProgids" "FirefoxHTML" ""
|
||||
!macroend
|
||||
!define AddAssociationIfNoneExist "!insertmacro AddAssociationIfNoneExist"
|
||||
|
||||
|
@ -418,7 +418,6 @@ ExDisp.h
|
||||
exe386.h
|
||||
execinfo.h
|
||||
extras.h
|
||||
fabdef.h
|
||||
fcntl.h
|
||||
features.h
|
||||
fibdef.h
|
||||
@ -628,7 +627,6 @@ libgnome/libgnome.h
|
||||
libgnomeui/gnome-icon-lookup.h
|
||||
libgnomeui/gnome-icon-theme.h
|
||||
libgnomeui/gnome-ui-init.h
|
||||
lib$routines.h
|
||||
limits
|
||||
limits.h
|
||||
link.h
|
||||
@ -889,7 +887,6 @@ resolv.h
|
||||
Resources.h
|
||||
Retrace.h
|
||||
rld_interface.h
|
||||
rmsdef.h
|
||||
Roster.h
|
||||
rpc.h
|
||||
rpcproxy.h
|
||||
@ -927,7 +924,6 @@ someincludefile.h
|
||||
Sound.h
|
||||
soundcard.h
|
||||
sqlite3.h
|
||||
ssdef.h
|
||||
sstream
|
||||
stack
|
||||
#ifdef ANDROID
|
||||
@ -1154,7 +1150,6 @@ unikbd.h
|
||||
unistd.h
|
||||
unix.h
|
||||
unixio.h
|
||||
unixlib.h
|
||||
unknwn.h
|
||||
UPrinting.h
|
||||
UQuickTime.h
|
||||
|
16
configure.in
16
configure.in
@ -9260,6 +9260,22 @@ export DIST
|
||||
export MOZ_LINKER
|
||||
export ZLIB_IN_MOZGLUE
|
||||
export MOZ_MEMORY
|
||||
export AR
|
||||
export RANLIB
|
||||
export CPP
|
||||
export CC
|
||||
export CXX
|
||||
export LD
|
||||
export ARFLAGS
|
||||
export CPPFLAGS
|
||||
export CFLAGS
|
||||
export CXXFLAGS
|
||||
export LDFLAGS
|
||||
export HOST_CC
|
||||
export HOST_CXX
|
||||
export HOST_CFLAGS
|
||||
export HOST_CXXFLAGS
|
||||
export HOST_LDFLAGS
|
||||
|
||||
if ! test -e js; then
|
||||
mkdir js
|
||||
|
@ -3,7 +3,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const DEFAULT_MAX_DEPTH = 3;
|
||||
const { Visitor, walk } = require("resource://devtools/shared/heapsnapshot/CensusUtils.js");
|
||||
|
||||
const DEFAULT_MAX_DEPTH = 4;
|
||||
const DEFAULT_MAX_SIBLINGS = 15;
|
||||
|
||||
/**
|
||||
@ -12,10 +14,16 @@ const DEFAULT_MAX_SIBLINGS = 15;
|
||||
* @param {NodeId} nodeId
|
||||
* @param {NodeSize} retainedSize
|
||||
*/
|
||||
function DominatorTreeNode(nodeId, retainedSize) {
|
||||
function DominatorTreeNode(nodeId, label, shallowSize, retainedSize) {
|
||||
// The id of this node.
|
||||
this.nodeId = nodeId;
|
||||
|
||||
// The label structure generated by describing the given node.
|
||||
this.label = label;
|
||||
|
||||
// The shallow size of this node.
|
||||
this.shallowSize = shallowSize;
|
||||
|
||||
// The retained size of this node.
|
||||
this.retainedSize = retainedSize;
|
||||
|
||||
@ -59,6 +67,109 @@ DominatorTreeNode.addChild = function (parent, child) {
|
||||
child.parentId = parent.nodeId;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Visitor that is used to generate a label for a node in the heap snapshot
|
||||
* and get its shallow size as well while we are at it.
|
||||
*/
|
||||
function LabelAndShallowSizeVisitor() {
|
||||
// As we walk the description, we accumulate edges in this array.
|
||||
this._labelPieces = [];
|
||||
|
||||
// Once we reach the non-zero count leaf node in the description, we move the
|
||||
// labelPieces here to signify that we no longer need to accumulate edges.
|
||||
this._label = undefined;
|
||||
|
||||
// Once we reach the non-zero count leaf node in the description, we grab the
|
||||
// shallow size and place it here.
|
||||
this._shallowSize = 0;
|
||||
}
|
||||
|
||||
DominatorTreeNode.LabelAndShallowSizeVisitor = LabelAndShallowSizeVisitor;
|
||||
|
||||
LabelAndShallowSizeVisitor.prototype = Object.create(Visitor);
|
||||
|
||||
/**
|
||||
* @overrides Visitor.prototype.enter
|
||||
*/
|
||||
LabelAndShallowSizeVisitor.prototype.enter = function (breakdown, report, edge) {
|
||||
if (this._labelPieces && edge) {
|
||||
this._labelPieces.push(edge);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @overrides Visitor.prototype.exit
|
||||
*/
|
||||
LabelAndShallowSizeVisitor.prototype.exit = function (breakdown, report, edge) {
|
||||
if (this._labelPieces && edge) {
|
||||
this._labelPieces.pop();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @overrides Visitor.prototype.count
|
||||
*/
|
||||
LabelAndShallowSizeVisitor.prototype.count = function (breakdown, report, edge) {
|
||||
if (report.count === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._label = this._labelPieces;
|
||||
this._labelPieces = undefined;
|
||||
|
||||
this._shallowSize = report.bytes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the generated label structure accumulated by this visitor.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
LabelAndShallowSizeVisitor.prototype.label = function () {
|
||||
return this._label;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the shallow size of the node this visitor visited.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
LabelAndShallowSizeVisitor.prototype.shallowSize = function () {
|
||||
return this._shallowSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a label structure for the node with the given id and grab its
|
||||
* shallow size.
|
||||
*
|
||||
* What is a "label" structure? HeapSnapshot.describeNode essentially takes a
|
||||
* census of a single node rather than the whole heap graph. The resulting
|
||||
* report has only one count leaf that is non-zero. The label structure is the
|
||||
* path in this report from the root to the non-zero count leaf.
|
||||
*
|
||||
* @param {Number} nodeId
|
||||
* @param {HeapSnapshot} snapshot
|
||||
* @param {Object} breakdown
|
||||
*
|
||||
* @returns {Object}
|
||||
* An object with the following properties:
|
||||
* - {Number} shallowSize
|
||||
* - {Object} label
|
||||
*/
|
||||
DominatorTreeNode.getLabelAndShallowSize = function (nodeId,
|
||||
snapshot,
|
||||
breakdown) {
|
||||
const description = snapshot.describeNode(breakdown, nodeId);
|
||||
|
||||
const visitor = new LabelAndShallowSizeVisitor();
|
||||
walk(breakdown, description, visitor);
|
||||
|
||||
return {
|
||||
label: visitor.label(),
|
||||
shallowSize: visitor.shallowSize(),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Do a partial traversal of the given dominator tree and convert it into a tree
|
||||
* of `DominatorTreeNode`s. Dominator trees have a node for every node in the
|
||||
@ -75,11 +186,15 @@ DominatorTreeNode.addChild = function (parent, child) {
|
||||
* @returns {DominatorTreeNode}
|
||||
*/
|
||||
DominatorTreeNode.partialTraversal = function (dominatorTree,
|
||||
snapshot,
|
||||
breakdown,
|
||||
maxDepth = DEFAULT_MAX_DEPTH,
|
||||
maxSiblings = DEFAULT_MAX_SIBLINGS) {
|
||||
function dfs(nodeId, depth) {
|
||||
const size = dominatorTree.getRetainedSize(nodeId);
|
||||
const node = new DominatorTreeNode(nodeId, size);
|
||||
const { label, shallowSize } =
|
||||
DominatorTreeNode.getLabelAndShallowSize(nodeId, snapshot, breakdown);
|
||||
const retainedSize = dominatorTree.getRetainedSize(nodeId);
|
||||
const node = new DominatorTreeNode(nodeId, label, shallowSize, retainedSize);
|
||||
const childNodeIds = dominatorTree.getImmediatelyDominated(nodeId);
|
||||
|
||||
const newDepth = depth + 1;
|
||||
|
@ -173,6 +173,8 @@ HeapAnalysesClient.prototype.computeDominatorTree = function (snapshotFilePath)
|
||||
* An object specifying options for this request.
|
||||
* - {DominatorTreeId} dominatorTreeId
|
||||
* The id of the dominator tree.
|
||||
* - {Object} breakdown
|
||||
* The breakdown used to generate node labels.
|
||||
* - {Number} maxDepth
|
||||
* The maximum depth to traverse down the tree to create this initial
|
||||
* view.
|
||||
@ -195,6 +197,8 @@ HeapAnalysesClient.prototype.getDominatorTree = function (opts) {
|
||||
* The id of the dominator tree.
|
||||
* - {NodeId} nodeId
|
||||
* The id of the node whose children are being found.
|
||||
* - {Object} breakdown
|
||||
* The breakdown used to generate node labels.
|
||||
* - {Number} startIndex
|
||||
* The starting index within the full set of immediately dominated
|
||||
* children of the children being requested. Children are always sorted
|
||||
|
@ -103,6 +103,13 @@ workerHelper.createTask(self, "getCreationTime", snapshotFilePath => {
|
||||
*/
|
||||
const dominatorTrees = [];
|
||||
|
||||
/**
|
||||
* The i^th HeapSnapshot in this array is the snapshot used to generate the i^th
|
||||
* dominator tree in `dominatorTrees` above. This lets us map from a dominator
|
||||
* tree id to the snapshot it came from.
|
||||
*/
|
||||
const dominatorTreeSnapshots = [];
|
||||
|
||||
/**
|
||||
* @see HeapAnalysesClient.prototype.computeDominatorTree
|
||||
*/
|
||||
@ -114,6 +121,7 @@ workerHelper.createTask(self, "computeDominatorTree", snapshotFilePath => {
|
||||
|
||||
const id = dominatorTrees.length;
|
||||
dominatorTrees.push(snapshot.computeDominatorTree());
|
||||
dominatorTreeSnapshots.push(snapshot);
|
||||
return id;
|
||||
});
|
||||
|
||||
@ -123,6 +131,7 @@ workerHelper.createTask(self, "computeDominatorTree", snapshotFilePath => {
|
||||
workerHelper.createTask(self, "getDominatorTree", request => {
|
||||
const {
|
||||
dominatorTreeId,
|
||||
breakdown,
|
||||
maxDepth,
|
||||
maxSiblings
|
||||
} = request;
|
||||
@ -132,7 +141,12 @@ workerHelper.createTask(self, "getDominatorTree", request => {
|
||||
`There does not exist a DominatorTree with the id ${dominatorTreeId}`);
|
||||
}
|
||||
|
||||
return DominatorTreeNode.partialTraversal(dominatorTrees[dominatorTreeId],
|
||||
const dominatorTree = dominatorTrees[dominatorTreeId];
|
||||
const snapshot = dominatorTreeSnapshots[dominatorTreeId];
|
||||
|
||||
return DominatorTreeNode.partialTraversal(dominatorTree,
|
||||
snapshot,
|
||||
breakdown,
|
||||
maxDepth,
|
||||
maxSiblings);
|
||||
});
|
||||
@ -144,6 +158,7 @@ workerHelper.createTask(self, "getImmediatelyDominated", request => {
|
||||
const {
|
||||
dominatorTreeId,
|
||||
nodeId,
|
||||
breakdown,
|
||||
startIndex,
|
||||
maxCount
|
||||
} = request;
|
||||
@ -154,6 +169,8 @@ workerHelper.createTask(self, "getImmediatelyDominated", request => {
|
||||
}
|
||||
|
||||
const dominatorTree = dominatorTrees[dominatorTreeId];
|
||||
const snapshot = dominatorTreeSnapshots[dominatorTreeId];
|
||||
|
||||
const childIds = dominatorTree.getImmediatelyDominated(nodeId);
|
||||
if (!childIds) {
|
||||
throw new Error(`${nodeId} is not a node id in the dominator tree`);
|
||||
@ -166,8 +183,10 @@ workerHelper.createTask(self, "getImmediatelyDominated", request => {
|
||||
const nodes = childIds
|
||||
.slice(start, end)
|
||||
.map(id => {
|
||||
const size = dominatorTree.getRetainedSize(id);
|
||||
const node = new DominatorTreeNode(id, size);
|
||||
const { label, shallowSize } =
|
||||
DominatorTreeNode.getLabelAndShallowSize(id, snapshot, breakdown);
|
||||
const retainedSize = dominatorTree.getRetainedSize(id);
|
||||
const node = new DominatorTreeNode(id, label, shallowSize, retainedSize);
|
||||
node.parentId = nodeId;
|
||||
// DominatorTree.getImmediatelyDominated will always return non-null here
|
||||
// because we got the id directly from the dominator tree.
|
||||
|
@ -522,6 +522,43 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HeapSnapshot::DescribeNode(JSContext* cx, JS::HandleObject breakdown, uint64_t nodeId,
|
||||
JS::MutableHandleValue rval, ErrorResult& rv) {
|
||||
MOZ_ASSERT(breakdown);
|
||||
JS::RootedValue breakdownVal(cx, JS::ObjectValue(*breakdown));
|
||||
JS::ubi::CountTypePtr rootType = JS::ubi::ParseBreakdown(cx, breakdownVal);
|
||||
if (NS_WARN_IF(!rootType)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::ubi::RootedCount rootCount(cx, rootType->makeCount());
|
||||
if (NS_WARN_IF(!rootCount)) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::ubi::Node::Id id(nodeId);
|
||||
Maybe<JS::ubi::Node> node = getNodeById(id);
|
||||
if (NS_WARN_IF(node.isNothing())) {
|
||||
rv.Throw(NS_ERROR_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
|
||||
MallocSizeOf mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf();
|
||||
if (NS_WARN_IF(!rootCount->count(mallocSizeOf, *node))) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!rootCount->report(cx, rval))) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<DominatorTree>
|
||||
HeapSnapshot::ComputeDominatorTree(ErrorResult& rv)
|
||||
{
|
||||
|
@ -159,6 +159,9 @@ public:
|
||||
void TakeCensus(JSContext* cx, JS::HandleObject options,
|
||||
JS::MutableHandleValue rval, ErrorResult& rv);
|
||||
|
||||
void DescribeNode(JSContext* cx, JS::HandleObject breakdown, uint64_t nodeId,
|
||||
JS::MutableHandleValue rval, ErrorResult& rv);
|
||||
|
||||
already_AddRefed<DominatorTree> ComputeDominatorTree(ErrorResult& rv);
|
||||
|
||||
dom::Nullable<uint64_t> GetCreationTime() {
|
||||
|
@ -22,6 +22,9 @@ const HeapAnalysesClient =
|
||||
const Services = require("Services");
|
||||
const { censusReportToCensusTreeNode } = require("devtools/shared/heapsnapshot/census-tree-node");
|
||||
const CensusUtils = require("devtools/shared/heapsnapshot/CensusUtils");
|
||||
const DominatorTreeNode = require("devtools/shared/heapsnapshot/DominatorTreeNode");
|
||||
const { LabelAndShallowSizeVisitor } = DominatorTreeNode;
|
||||
|
||||
|
||||
// Always log packets when running tests. runxpcshelltests.py will throw
|
||||
// the output away anyway, unless you give it the --verbose flag.
|
||||
@ -296,3 +299,29 @@ function assertDiff(breakdown, first, second, expected) {
|
||||
|
||||
assertStructurallyEquivalent(actual, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that creating a label and getting a shallow size from the given node
|
||||
* description with the specified breakdown is as expected.
|
||||
*
|
||||
* @param {Object} breakdown
|
||||
* @param {Object} givenDescription
|
||||
* @param {Number} expectedShallowSize
|
||||
* @param {Object} expectedLabel
|
||||
*/
|
||||
function assertLabelAndShallowSize(breakdown, givenDescription, expectedShallowSize, expectedLabel) {
|
||||
dumpn("Computing label and shallow size from node description:");
|
||||
dumpn("Breakdown: " + JSON.stringify(breakdown, null, 4));
|
||||
dumpn("Given description: " + JSON.stringify(givenDescription, null, 4));
|
||||
|
||||
const visitor = new LabelAndShallowSizeVisitor();
|
||||
CensusUtils.walk(breakdown, description, visitor);
|
||||
|
||||
dumpn("Expected shallow size: " + expectedShallowSize);
|
||||
dumpn("Actual shallow size: " + visitor.shallowSize());
|
||||
equal(visitor.shallowSize(), expectedShallowSize, "Shallow size should be correct");
|
||||
|
||||
dumpn("Expected label: " + JSON.stringify(expectedLabel, null, 4));
|
||||
dumpn("Actual label: " + JSON.stringify(visitor.label(), null, 4));
|
||||
assertStructurallyEquivalent(visitor.label(), expectedLabel);
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can generate label structures from node description reports.
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: {
|
||||
by: "objectClass",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
strings: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
scripts: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
other: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
objects: {
|
||||
Function: { count: 1, bytes: 32 },
|
||||
other: { count: 0, bytes: 0 }
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
"objects",
|
||||
"Function"
|
||||
];
|
||||
|
||||
const shallowSize = 32;
|
||||
|
||||
function run_test() {
|
||||
assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can generate label structures from node description reports.
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: {
|
||||
by: "objectClass",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
strings: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
scripts: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
other: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
objects: {
|
||||
other: { count: 1, bytes: 10 }
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
"objects",
|
||||
"other"
|
||||
];
|
||||
|
||||
const shallowSize = 10;
|
||||
|
||||
function run_test() {
|
||||
assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can generate label structures from node description reports.
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: {
|
||||
by: "objectClass",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
strings: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
scripts: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
other: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
objects: {
|
||||
other: { count: 0, bytes: 0 }
|
||||
},
|
||||
strings: {
|
||||
"JSString": { count: 1, bytes: 42 },
|
||||
},
|
||||
scripts: {},
|
||||
other: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
"strings",
|
||||
"JSString"
|
||||
];
|
||||
|
||||
const shallowSize = 42;
|
||||
|
||||
function run_test() {
|
||||
assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can generate label structures from node description reports.
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: {
|
||||
by: "objectClass",
|
||||
then: {
|
||||
by: "allocationStack",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
noStack: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
strings: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
scripts: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
other: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const stack = saveStack();
|
||||
|
||||
const description = {
|
||||
objects: {
|
||||
Array: new Map([[stack, { count: 1, bytes: 512 }]]),
|
||||
other: { count: 0, bytes: 0 }
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
"objects",
|
||||
"Array",
|
||||
stack
|
||||
];
|
||||
|
||||
const shallowSize = 512;
|
||||
|
||||
function run_test() {
|
||||
assertLabelAndShallowSize(breakdown, description, shallowSize, expected);
|
||||
}
|
@ -7,6 +7,14 @@ function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: { by: "count", count: true, bytes: true },
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
add_task(function* () {
|
||||
const client = new HeapAnalysesClient();
|
||||
|
||||
@ -18,7 +26,10 @@ add_task(function* () {
|
||||
equal(typeof dominatorTreeId, "number",
|
||||
"should get a dominator tree id, and it should be a number");
|
||||
|
||||
const partialTree = yield client.getDominatorTree({ dominatorTreeId });
|
||||
const partialTree = yield client.getDominatorTree({
|
||||
dominatorTreeId,
|
||||
breakdown
|
||||
});
|
||||
ok(partialTree, "Should get a partial tree");
|
||||
equal(typeof partialTree, "object",
|
||||
"partialTree should be an object");
|
||||
|
@ -8,12 +8,20 @@ function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: { by: "count", count: true, bytes: true },
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
add_task(function* () {
|
||||
const client = new HeapAnalysesClient();
|
||||
|
||||
let threw = false;
|
||||
try {
|
||||
yield client.getDominatorTree({ dominatorTreeId: 42 });
|
||||
yield client.getDominatorTree({ dominatorTreeId: 42, breakdown });
|
||||
} catch (_) {
|
||||
threw = true;
|
||||
}
|
||||
|
@ -7,6 +7,14 @@ function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: { by: "count", count: true, bytes: true },
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
add_task(function* () {
|
||||
const client = new HeapAnalysesClient();
|
||||
|
||||
@ -14,13 +22,17 @@ add_task(function* () {
|
||||
yield client.readHeapSnapshot(snapshotFilePath);
|
||||
const dominatorTreeId = yield client.computeDominatorTree(snapshotFilePath);
|
||||
|
||||
const partialTree = yield client.getDominatorTree({ dominatorTreeId });
|
||||
const partialTree = yield client.getDominatorTree({
|
||||
dominatorTreeId,
|
||||
breakdown
|
||||
});
|
||||
ok(partialTree.children.length > 0,
|
||||
"root should immediately dominate some nodes");
|
||||
|
||||
// First, test getting a subset of children available.
|
||||
const response = yield client.getImmediatelyDominated({
|
||||
dominatorTreeId,
|
||||
breakdown,
|
||||
nodeId: partialTree.nodeId,
|
||||
startIndex: 0,
|
||||
maxCount: partialTree.children.length - 1
|
||||
@ -33,6 +45,7 @@ add_task(function* () {
|
||||
// Next, test getting a subset of children available.
|
||||
const secondResponse = yield client.getImmediatelyDominated({
|
||||
dominatorTreeId,
|
||||
breakdown,
|
||||
nodeId: partialTree.nodeId,
|
||||
startIndex: 0,
|
||||
maxCount: Infinity
|
||||
|
@ -0,0 +1,42 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can describe nodes with a breakdown.
|
||||
|
||||
function run_test() {
|
||||
const path = saveNewHeapSnapshot();
|
||||
const snapshot = ChromeUtils.readHeapSnapshot(path);
|
||||
ok(snapshot.describeNode);
|
||||
equal(typeof snapshot.describeNode, "function");
|
||||
|
||||
const dt = snapshot.computeDominatorTree();
|
||||
|
||||
let threw = false;
|
||||
try {
|
||||
snapshot.describeNode(undefined, dt.root);
|
||||
} catch (_) {
|
||||
threw = true;
|
||||
}
|
||||
ok(threw, "Should require a breakdown");
|
||||
|
||||
const breakdown = {
|
||||
by: "coarseType",
|
||||
objects: { by: "objectClass" },
|
||||
scripts: { by: "internalType" },
|
||||
strings: { by: "internalType" },
|
||||
other: { by: "internalType" }
|
||||
};
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
snapshot.describeNode(breakdown, 0);
|
||||
} catch (_) {
|
||||
threw = true;
|
||||
}
|
||||
ok(threw, "Should throw when given an invalid node id");
|
||||
|
||||
const description = snapshot.describeNode(breakdown, dt.root);
|
||||
ok(description);
|
||||
ok(description.other);
|
||||
ok(description.other["JS::ubi::RootList"]);
|
||||
}
|
@ -33,6 +33,10 @@ support-files =
|
||||
[test_DominatorTree_03.js]
|
||||
[test_DominatorTree_04.js]
|
||||
[test_DominatorTree_05.js]
|
||||
[test_DominatorTreeNode_LabelAndShallowSize_01.js]
|
||||
[test_DominatorTreeNode_LabelAndShallowSize_02.js]
|
||||
[test_DominatorTreeNode_LabelAndShallowSize_03.js]
|
||||
[test_DominatorTreeNode_LabelAndShallowSize_04.js]
|
||||
[test_HeapAnalyses_computeDominatorTree_01.js]
|
||||
[test_HeapAnalyses_computeDominatorTree_02.js]
|
||||
[test_HeapAnalyses_getCreationTime_01.js]
|
||||
@ -51,6 +55,7 @@ support-files =
|
||||
[test_HeapAnalyses_takeCensus_07.js]
|
||||
[test_HeapSnapshot_creationTime_01.js]
|
||||
[test_HeapSnapshot_deepStack_01.js]
|
||||
[test_HeapSnapshot_describeNode_01.js]
|
||||
[test_HeapSnapshot_takeCensus_01.js]
|
||||
[test_HeapSnapshot_takeCensus_02.js]
|
||||
[test_HeapSnapshot_takeCensus_03.js]
|
||||
|
@ -12,7 +12,6 @@ support-files =
|
||||
file_use_counter_svg_fill_pattern_data.svg
|
||||
|
||||
[browser_bug593387.js]
|
||||
skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
|
||||
[browser_bug902350.js]
|
||||
tags = mcb
|
||||
[browser_messagemanager_loadprocessscript.js]
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "WebGL2Context.h"
|
||||
#include "GLContext.h"
|
||||
#include "WebGLQuery.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -255,6 +257,7 @@ WebGL2Context::EndQuery(GLenum target)
|
||||
}
|
||||
|
||||
UpdateBoundQuery(target, nullptr);
|
||||
NS_DispatchToCurrentThread(new WebGLQuery::AvailableRunnable(activeQuery));
|
||||
}
|
||||
|
||||
already_AddRefed<WebGLQuery>
|
||||
@ -325,6 +328,11 @@ WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname,
|
||||
return;
|
||||
}
|
||||
|
||||
// We must wait for an event loop before the query can be available
|
||||
if (!query->mCanBeAvailable && !gfxPrefs::WebGLImmediateQueries()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
GLuint returned = 0;
|
||||
switch (pname) {
|
||||
|
@ -785,7 +785,7 @@ FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
|
||||
|
||||
// GLES 3.0.4, p147, table 3.19
|
||||
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
|
||||
|
||||
#if ALLOW_ES3_FORMATS
|
||||
// Note that all compressed texture formats are filterable:
|
||||
// GLES 3.0.4 p161:
|
||||
// "[A] texture is complete unless any of the following conditions hold true:
|
||||
@ -805,7 +805,7 @@ FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
|
||||
fnAllowES3TexFormat(FOO(COMPRESSED_SIGNED_RG11_EAC ), false, true);
|
||||
fnAllowES3TexFormat(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), false, true);
|
||||
fnAllowES3TexFormat(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), false, true);
|
||||
|
||||
#endif
|
||||
#undef FOO
|
||||
|
||||
// GLES 3.0.4, p206, "Required Renderbuffer Formats":
|
||||
|
@ -20,6 +20,7 @@ WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
|
||||
WebGLQuery::WebGLQuery(WebGLContext* webgl)
|
||||
: WebGLContextBoundObject(webgl)
|
||||
, mCanBeAvailable(false)
|
||||
, mGLName(0)
|
||||
, mType(0)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -22,6 +23,19 @@ class WebGLQuery final
|
||||
public:
|
||||
explicit WebGLQuery(WebGLContext* webgl);
|
||||
|
||||
class AvailableRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit AvailableRunnable(WebGLQuery* query) : mQuery(query) { }
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
mQuery->mCanBeAvailable = true;
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
const RefPtr<WebGLQuery> mQuery;
|
||||
};
|
||||
|
||||
bool IsActive() const;
|
||||
|
||||
bool HasEverBeenActive() const {
|
||||
@ -42,6 +56,8 @@ public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
|
||||
|
||||
// Track whether the event loop has spun
|
||||
bool mCanBeAvailable;
|
||||
|
||||
private:
|
||||
~WebGLQuery() {
|
||||
|
@ -14401,12 +14401,7 @@ ctx.moveTo(50, 25);
|
||||
ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
|
||||
ctx.stroke();
|
||||
|
||||
if (IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -14438,11 +14433,7 @@ ctx.moveTo(50, 25);
|
||||
ctx.lineTo(50, 25);
|
||||
ctx.stroke();
|
||||
|
||||
if (IsAzureSkia()) {
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
} else {
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
}
|
||||
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
}
|
||||
</script>
|
||||
|
@ -271,6 +271,13 @@ DeviceStorageStatics::DumpDirs()
|
||||
nullptr
|
||||
};
|
||||
|
||||
const char* ptStr;
|
||||
if (XRE_IsParentProcess()) {
|
||||
ptStr = "parent";
|
||||
} else {
|
||||
ptStr = "child";
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < TYPE_COUNT; ++i) {
|
||||
MOZ_ASSERT(storageTypes[i]);
|
||||
|
||||
@ -278,8 +285,8 @@ DeviceStorageStatics::DumpDirs()
|
||||
if (mDirs[i]) {
|
||||
mDirs[i]->GetPath(path);
|
||||
}
|
||||
DS_LOG_INFO("%s: '%s'",
|
||||
storageTypes[i], NS_LossyConvertUTF16toASCII(path).get());
|
||||
DS_LOG_INFO("(%s) %s: '%s'",
|
||||
ptStr, storageTypes[i], NS_LossyConvertUTF16toASCII(path).get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -297,6 +304,47 @@ DeviceStorageStatics::Shutdown()
|
||||
Preferences::RemoveObserver(this, kPrefWritableName);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
DeviceStorageStatics::GetDeviceStorageAreasForIPC(
|
||||
DeviceStorageAreaInfo& aAreaInfo)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InitializeDirs();
|
||||
|
||||
GetDirPath(TYPE_APPS, aAreaInfo.apps());
|
||||
GetDirPath(TYPE_CRASHES, aAreaInfo.crashes());
|
||||
GetDirPath(TYPE_PICTURES, aAreaInfo.pictures());
|
||||
GetDirPath(TYPE_VIDEOS, aAreaInfo.videos());
|
||||
GetDirPath(TYPE_MUSIC, aAreaInfo.music());
|
||||
GetDirPath(TYPE_SDCARD, aAreaInfo.sdcard());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
DeviceStorageStatics::RecvDeviceStorageAreasFromParent(
|
||||
const DeviceStorageAreaInfo& aAreaInfo)
|
||||
{
|
||||
if (XRE_IsParentProcess()) {
|
||||
// We are the parent. Therefore our info is already correct.
|
||||
return;
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (NS_WARN_IF(!sInstance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_NewLocalFile(aAreaInfo.apps(), true, getter_AddRefs(sInstance->mDirs[TYPE_APPS]));
|
||||
NS_NewLocalFile(aAreaInfo.crashes(), true, getter_AddRefs(sInstance->mDirs[TYPE_CRASHES]));
|
||||
NS_NewLocalFile(aAreaInfo.pictures(), true, getter_AddRefs(sInstance->mDirs[TYPE_PICTURES]));
|
||||
NS_NewLocalFile(aAreaInfo.videos(), true, getter_AddRefs(sInstance->mDirs[TYPE_VIDEOS]));
|
||||
NS_NewLocalFile(aAreaInfo.music(), true, getter_AddRefs(sInstance->mDirs[TYPE_MUSIC]));
|
||||
NS_NewLocalFile(aAreaInfo.sdcard(), true, getter_AddRefs(sInstance->mDirs[TYPE_SDCARD]));
|
||||
|
||||
sInstance->mInitialized = true;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIFile>
|
||||
DeviceStorageStatics::GetDir(DeviceStorageType aType)
|
||||
{
|
||||
@ -332,6 +380,16 @@ DeviceStorageStatics::GetDir(DeviceStorageType aType)
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
DeviceStorageStatics::GetDirPath(DeviceStorageType aType, nsString& aDirPath)
|
||||
{
|
||||
aDirPath.Truncate();
|
||||
nsCOMPtr<nsIFile> file = GetDir(aType);
|
||||
if (file) {
|
||||
file->GetPath(aDirPath);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DeviceStorageStatics::HasOverrideRootDir()
|
||||
{
|
||||
|
@ -8,7 +8,12 @@
|
||||
#define mozilla_dom_devicestorage_DeviceStorageStatics_h
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsArrayUtils.h"
|
||||
|
||||
class nsString;
|
||||
class nsDOMDeviceStorage;
|
||||
class DeviceStorageFile;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -35,6 +40,9 @@ public:
|
||||
static void GetWritableName(nsString& aName);
|
||||
static void SetWritableName(const nsAString& aName);
|
||||
|
||||
static void GetDeviceStorageAreasForIPC(DeviceStorageAreaInfo& aAreaInfo);
|
||||
static void RecvDeviceStorageAreasFromParent(const DeviceStorageAreaInfo& aAreaInfo);
|
||||
|
||||
static bool HasOverrideRootDir();
|
||||
static already_AddRefed<nsIFile> GetAppsDir();
|
||||
static already_AddRefed<nsIFile> GetCrashesDir();
|
||||
@ -56,6 +64,7 @@ private:
|
||||
};
|
||||
|
||||
static already_AddRefed<nsIFile> GetDir(DeviceStorageType aType);
|
||||
static void GetDirPath(DeviceStorageType aType, nsString& aString);
|
||||
|
||||
DeviceStorageStatics();
|
||||
virtual ~DeviceStorageStatics();
|
||||
|
@ -1883,6 +1883,11 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
aGraph = MediaStreamGraph::GetInstance(graphDriverType, mAudioChannel);
|
||||
}
|
||||
|
||||
if (!mOutputStreams.IsEmpty() &&
|
||||
aGraph != mOutputStreams[0].mStream->GetInputStream()->Graph()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OutputMediaStream* out = mOutputStreams.AppendElement();
|
||||
out->mStream = DOMMediaStream::CreateTrackUnionStream(window, aGraph);
|
||||
RefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "BlobChild.h"
|
||||
#include "CrashReporterChild.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "DeviceStorageStatics.h"
|
||||
#include "TabChild.h"
|
||||
#include "HandlerServiceChild.h"
|
||||
|
||||
@ -2594,6 +2595,15 @@ ContentChild::RecvVolumes(nsTArray<VolumeInfo>&& aVolumes)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvDeviceStorageAreas(const DeviceStorageAreaInfo& areaInfo)
|
||||
{
|
||||
#if !defined(MOZ_WIDGET_GONK)
|
||||
DeviceStorageStatics::RecvDeviceStorageAreasFromParent(areaInfo);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvFilePathUpdate(const nsString& aStorageType,
|
||||
const nsString& aStorageName,
|
||||
|
@ -383,6 +383,7 @@ public:
|
||||
virtual bool RecvLastPrivateDocShellDestroyed() override;
|
||||
|
||||
virtual bool RecvVolumes(InfallibleTArray<VolumeInfo>&& aVolumes) override;
|
||||
virtual bool RecvDeviceStorageAreas(const DeviceStorageAreaInfo& areaInfo) override;
|
||||
virtual bool RecvFilePathUpdate(const nsString& aStorageType,
|
||||
const nsString& aStorageName,
|
||||
const nsString& aPath,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "AudioChannelService.h"
|
||||
#include "BlobParent.h"
|
||||
#include "CrashReporterParent.h"
|
||||
#include "DeviceStorageStatics.h"
|
||||
#include "GMPServiceParent.h"
|
||||
#include "HandlerServiceParent.h"
|
||||
#include "IHistory.h"
|
||||
@ -1606,6 +1607,10 @@ ContentParent::ForwardKnownInfo()
|
||||
vs->GetVolumesForIPC(&volumeInfo);
|
||||
Unused << SendVolumes(volumeInfo);
|
||||
}
|
||||
#else
|
||||
DeviceStorageAreaInfo areaInfo;
|
||||
DeviceStorageStatics::GetDeviceStorageAreasForIPC(areaInfo);
|
||||
Unused << SendDeviceStorageAreas(areaInfo);
|
||||
#endif /* MOZ_WIDGET_GONK */
|
||||
|
||||
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
|
||||
|
@ -364,6 +364,15 @@ struct VolumeInfo {
|
||||
bool isHotSwappable;
|
||||
};
|
||||
|
||||
struct DeviceStorageAreaInfo {
|
||||
nsString music;
|
||||
nsString pictures;
|
||||
nsString videos;
|
||||
nsString sdcard;
|
||||
nsString apps;
|
||||
nsString crashes;
|
||||
};
|
||||
|
||||
struct ClipboardCapabilities {
|
||||
bool supportsSelectionClipboard;
|
||||
bool supportsFindClipboard;
|
||||
@ -595,6 +604,8 @@ child:
|
||||
|
||||
Volumes(VolumeInfo[] volumes);
|
||||
|
||||
DeviceStorageAreas(DeviceStorageAreaInfo areaInfo);
|
||||
|
||||
FlushMemory(nsString reason);
|
||||
|
||||
GarbageCollect();
|
||||
|
@ -57,6 +57,7 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
|
||||
GraphTime aLastSwitchNextIterationStart,
|
||||
GraphTime aLastSwitchNextIterationEnd)
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
// We set mIterationEnd here, because the first thing a driver do when it
|
||||
// does an iteration is to update graph times, so we are in fact setting
|
||||
// mIterationStart of the next iteration by setting the end of the previous
|
||||
@ -64,13 +65,14 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
|
||||
mIterationStart = aLastSwitchNextIterationStart;
|
||||
mIterationEnd = aLastSwitchNextIterationEnd;
|
||||
|
||||
STREAM_LOG(LogLevel::Debug, ("Setting previous driver: %p (%s)", aPreviousDriver, aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
|
||||
MOZ_ASSERT(!mPreviousDriver);
|
||||
mPreviousDriver = aPreviousDriver;
|
||||
STREAM_LOG(LogLevel::Debug, ("Setting previous driver: %p (%s)", PreviousDriver(), PreviousDriver()->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
|
||||
MOZ_ASSERT(!PreviousDriver());
|
||||
SetPreviousDriver(aPreviousDriver);
|
||||
}
|
||||
|
||||
void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
// This is the situation where `mPreviousDriver` is an AudioCallbackDriver
|
||||
// that is switching device, and the graph has found the current driver is not
|
||||
// an AudioCallbackDriver, but tries to switch to a _new_ AudioCallbackDriver
|
||||
@ -78,23 +80,15 @@ void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
|
||||
// request to switch, since we know we will switch back to the old
|
||||
// AudioCallbackDriver when it has recovered from the device switching.
|
||||
if (aNextDriver->AsAudioCallbackDriver() &&
|
||||
mPreviousDriver &&
|
||||
mPreviousDriver->AsAudioCallbackDriver()->IsSwitchingDevice() &&
|
||||
mPreviousDriver != aNextDriver) {
|
||||
PreviousDriver() &&
|
||||
PreviousDriver()->AsAudioCallbackDriver()->IsSwitchingDevice() &&
|
||||
PreviousDriver() != aNextDriver) {
|
||||
return;
|
||||
}
|
||||
LIFECYCLE_LOG("Switching to new driver: %p (%s)",
|
||||
aNextDriver, aNextDriver->AsAudioCallbackDriver() ?
|
||||
"AudioCallbackDriver" : "SystemClockDriver");
|
||||
mNextDriver = aNextDriver;
|
||||
}
|
||||
|
||||
void GraphDriver::EnsureImmediateWakeUpLocked()
|
||||
{
|
||||
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
|
||||
mWaitState = WAITSTATE_WAKING_UP;
|
||||
mGraphImpl->mGraphDriverAsleep = false; // atomic
|
||||
mGraphImpl->GetMonitor().Notify();
|
||||
SetNextDriver(aNextDriver);
|
||||
}
|
||||
|
||||
GraphTime
|
||||
@ -151,6 +145,36 @@ void GraphDriver::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphDriver::Switching()
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
return mNextDriver || mPreviousDriver;
|
||||
}
|
||||
|
||||
GraphDriver* GraphDriver::NextDriver()
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
return mNextDriver;
|
||||
}
|
||||
|
||||
GraphDriver* GraphDriver::PreviousDriver()
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
return mPreviousDriver;
|
||||
}
|
||||
|
||||
void GraphDriver::SetNextDriver(GraphDriver* aNextDriver)
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
mNextDriver = aNextDriver;
|
||||
}
|
||||
|
||||
void GraphDriver::SetPreviousDriver(GraphDriver* aPreviousDriver)
|
||||
{
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
mPreviousDriver = aPreviousDriver;
|
||||
}
|
||||
|
||||
ThreadedDriver::ThreadedDriver(MediaStreamGraphImpl* aGraphImpl)
|
||||
: GraphDriver(aGraphImpl)
|
||||
{ }
|
||||
@ -174,20 +198,28 @@ public:
|
||||
profiler_register_thread("MediaStreamGraph", &aLocal);
|
||||
LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
|
||||
mDriver->mGraphImpl);
|
||||
if (mDriver->mPreviousDriver) {
|
||||
|
||||
GraphDriver* previousDriver = nullptr;
|
||||
{
|
||||
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
|
||||
previousDriver = mDriver->PreviousDriver();
|
||||
}
|
||||
if (previousDriver) {
|
||||
LIFECYCLE_LOG("%p releasing an AudioCallbackDriver(%p), for graph %p\n",
|
||||
mDriver,
|
||||
mDriver->mPreviousDriver.get(),
|
||||
previousDriver,
|
||||
mDriver->GraphImpl());
|
||||
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
|
||||
// Stop and release the previous driver off-main-thread, but only if we're
|
||||
// not in the situation where we've fallen back to a system clock driver
|
||||
// because the osx audio stack is currently switching output device.
|
||||
if (!mDriver->mPreviousDriver->AsAudioCallbackDriver()->IsSwitchingDevice()) {
|
||||
if (!previousDriver->AsAudioCallbackDriver()->IsSwitchingDevice()) {
|
||||
RefPtr<AsyncCubebTask> releaseEvent =
|
||||
new AsyncCubebTask(mDriver->mPreviousDriver->AsAudioCallbackDriver(), AsyncCubebOperation::SHUTDOWN);
|
||||
mDriver->mPreviousDriver = nullptr;
|
||||
new AsyncCubebTask(previousDriver->AsAudioCallbackDriver(), AsyncCubebOperation::SHUTDOWN);
|
||||
releaseEvent->Dispatch();
|
||||
|
||||
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
|
||||
mDriver->SetPreviousDriver(nullptr);
|
||||
}
|
||||
} else {
|
||||
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
|
||||
@ -228,10 +260,10 @@ ThreadedDriver::Revive()
|
||||
// If we were switching, switch now. Otherwise, tell thread to run the main
|
||||
// loop again.
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
if (mNextDriver) {
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
if (NextDriver()) {
|
||||
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(NextDriver());
|
||||
NextDriver()->Start();
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
|
||||
mThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
@ -302,11 +334,12 @@ ThreadedDriver::RunThread()
|
||||
|
||||
stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
|
||||
|
||||
if (mNextDriver && stillProcessing) {
|
||||
MonitorAutoLock lock(GraphImpl()->GetMonitor());
|
||||
if (NextDriver() && stillProcessing) {
|
||||
STREAM_LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(NextDriver());
|
||||
NextDriver()->Start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -373,8 +406,7 @@ SystemClockDriver::WaitForNextIteration()
|
||||
mGraphImpl->mNeedAnotherIteration = false;
|
||||
}
|
||||
|
||||
void
|
||||
SystemClockDriver::WakeUp()
|
||||
void SystemClockDriver::WakeUp()
|
||||
{
|
||||
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
|
||||
mWaitState = WAITSTATE_WAKING_UP;
|
||||
@ -509,7 +541,6 @@ AudioCallbackDriver::AudioCallbackDriver(MediaStreamGraphImpl* aGraphImpl)
|
||||
, mStarted(false)
|
||||
, mAudioChannel(aGraphImpl->AudioChannel())
|
||||
, mInCallback(false)
|
||||
, mPauseRequested(false)
|
||||
, mMicrophoneActive(false)
|
||||
#ifdef XP_MACOSX
|
||||
, mCallbackReceivedWhileSwitching(0)
|
||||
@ -568,12 +599,13 @@ AudioCallbackDriver::Init()
|
||||
} else {
|
||||
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
|
||||
// Fall back to a driver using a normal thread.
|
||||
mNextDriver = new SystemClockDriver(GraphImpl());
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
MonitorAutoLock lock(GraphImpl()->GetMonitor());
|
||||
SetNextDriver(new SystemClockDriver(GraphImpl()));
|
||||
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(NextDriver());
|
||||
DebugOnly<bool> found = mGraphImpl->RemoveMixerCallback(this);
|
||||
NS_WARN_IF_FALSE(!found, "Mixer callback not added when switching?");
|
||||
mNextDriver->Start();
|
||||
NextDriver()->Start();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -614,18 +646,23 @@ AudioCallbackDriver::Start()
|
||||
initEvent->Dispatch();
|
||||
} else {
|
||||
STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from the previous driver's thread", mGraphImpl));
|
||||
Init();
|
||||
{
|
||||
MonitorAutoUnlock mon(GraphImpl()->GetMonitor());
|
||||
Init();
|
||||
}
|
||||
|
||||
// Check if we need to resolve promises because the driver just got switched
|
||||
// because of a resuming AudioContext
|
||||
if (!mPromisesForOperation.IsEmpty()) {
|
||||
// CompleteAudioContextOperations takes the lock as needed
|
||||
MonitorAutoUnlock mon(GraphImpl()->GetMonitor());
|
||||
CompleteAudioContextOperations(AsyncCubebOperation::INIT);
|
||||
}
|
||||
|
||||
if (mPreviousDriver) {
|
||||
if (PreviousDriver()) {
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
new MediaStreamGraphShutdownThreadRunnable(mPreviousDriver);
|
||||
mPreviousDriver = nullptr;
|
||||
new MediaStreamGraphShutdownThreadRunnable(PreviousDriver());
|
||||
SetPreviousDriver(nullptr);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
}
|
||||
@ -661,10 +698,10 @@ AudioCallbackDriver::Revive()
|
||||
STREAM_LOG(LogLevel::Debug, ("AudioCallbackDriver reviving."));
|
||||
// If we were switching, switch now. Otherwise, start the audio thread again.
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
if (mNextDriver) {
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
if (NextDriver()) {
|
||||
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(NextDriver());
|
||||
NextDriver()->Start();
|
||||
} else {
|
||||
STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
|
||||
RefPtr<AsyncCubebTask> initEvent =
|
||||
@ -743,7 +780,7 @@ AudioCallbackDriver::OSXDeviceSwitchingWorkaround()
|
||||
// the self reference and unref the SystemClockDriver we fallen back on.
|
||||
if (GraphImpl()->CurrentDriver() == this) {
|
||||
mSelfReference.Drop(this);
|
||||
mNextDriver = nullptr;
|
||||
SetNextDriver(nullptr);
|
||||
} else {
|
||||
GraphImpl()->CurrentDriver()->SwitchAtNextIteration(this);
|
||||
}
|
||||
@ -761,11 +798,6 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
|
||||
{
|
||||
bool stillProcessing;
|
||||
|
||||
if (mPauseRequested) {
|
||||
PodZero(aBuffer, aFrames * mGraphImpl->AudioChannelCount());
|
||||
return aFrames;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (OSXDeviceSwitchingWorkaround()) {
|
||||
PodZero(aBuffer, aFrames * mGraphImpl->AudioChannelCount());
|
||||
@ -853,19 +885,23 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
|
||||
|
||||
mBuffer.BufferFilled();
|
||||
|
||||
if (mNextDriver && stillProcessing) {
|
||||
{
|
||||
// If the audio stream has not been started by the previous driver or
|
||||
// the graph itself, keep it alive.
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
if (!IsStarted()) {
|
||||
return aFrames;
|
||||
}
|
||||
bool switching = false;
|
||||
{
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
switching = !!NextDriver();
|
||||
}
|
||||
|
||||
if (switching && stillProcessing) {
|
||||
// If the audio stream has not been started by the previous driver or
|
||||
// the graph itself, keep it alive.
|
||||
MonitorAutoLock mon(mGraphImpl->GetMonitor());
|
||||
if (!IsStarted()) {
|
||||
return aFrames;
|
||||
}
|
||||
STREAM_LOG(LogLevel::Debug, ("Switching to system driver."));
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(NextDriver());
|
||||
NextDriver()->Start();
|
||||
// Returning less than aFrames starts the draining and eventually stops the
|
||||
// audio thread. This function will never get called again.
|
||||
return aFrames - 1;
|
||||
@ -968,7 +1004,7 @@ AudioCallbackDriver::DeviceChangedCallback() {
|
||||
STREAM_LOG(LogLevel::Error, ("Switching to SystemClockDriver during output switch"));
|
||||
mSelfReference.Take(this);
|
||||
mCallbackReceivedWhileSwitching = 0;
|
||||
mNextDriver = new SystemClockDriver(GraphImpl());
|
||||
SetNextDriver(new SystemClockDriver(GraphImpl()));
|
||||
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
|
||||
mGraphImpl->SetCurrentDriver(mNextDriver);
|
||||
mNextDriver->Start();
|
||||
|
@ -61,6 +61,46 @@ class OfflineClockDriver;
|
||||
* OfflineClockDriver, if the graph is offline, or a SystemClockDriver, if the
|
||||
* graph is real time.
|
||||
* A MediaStreamGraph holds an owning reference to its driver.
|
||||
*
|
||||
* The lifetime of drivers is a complicated affair. Here are the different
|
||||
* scenarii that can happen:
|
||||
*
|
||||
* Starting a MediaStreamGraph with an AudioCallbackDriver
|
||||
* - A new thread T is created, from the main thread.
|
||||
* - On this thread T, cubeb is initialized if needed, and a cubeb_stream is
|
||||
* created and started
|
||||
* - The thread T posts a message to the main thread to terminate itself.
|
||||
* - The graph runs off the audio thread
|
||||
*
|
||||
* Starting a MediaStreamGraph with a SystemClockDriver:
|
||||
* - A new thread T is created from the main thread.
|
||||
* - The graph runs off this thread.
|
||||
*
|
||||
* Switching from a SystemClockDriver to an AudioCallbackDriver:
|
||||
* - A new AudioCallabackDriver is created and initialized on the graph thread
|
||||
* - At the end of the MSG iteration, the SystemClockDriver transfers its timing
|
||||
* info and a reference to itself to the AudioCallbackDriver. It then starts
|
||||
* the AudioCallbackDriver.
|
||||
* - When the AudioCallbackDriver starts, it checks if it has been switched from
|
||||
* a SystemClockDriver, and if that is the case, sends a message to the main
|
||||
* thread to shut the SystemClockDriver thread down.
|
||||
* - The graph now runs off an audio callback
|
||||
*
|
||||
* Switching from an AudioCallbackDriver to a SystemClockDriver:
|
||||
* - A new SystemClockDriver is created, and set as mNextDriver.
|
||||
* - At the end of the MSG iteration, the AudioCallbackDriver transfers its
|
||||
* timing info and a reference to itself to the SystemClockDriver. A new
|
||||
* SystemClockDriver is started from the current audio thread.
|
||||
* - When starting, the SystemClockDriver checks if it has been switched from an
|
||||
* AudioCallbackDriver. If yes, it creates a new temporary thread to release
|
||||
* the cubeb_streams. This temporary thread closes the cubeb_stream, and
|
||||
* then dispatches a message to the main thread to be terminated.
|
||||
* - The graph now runs off a normal thread.
|
||||
*
|
||||
* Two drivers cannot run at the same time for the same graph. The thread safety
|
||||
* of the different attributes of drivers, and they access pattern is documented
|
||||
* next to the members themselves.
|
||||
*
|
||||
*/
|
||||
class GraphDriver
|
||||
{
|
||||
@ -92,14 +132,14 @@ public:
|
||||
virtual uint32_t IterationDuration() = 0;
|
||||
|
||||
/* Return whether we are switching or not. */
|
||||
bool Switching() {
|
||||
return mNextDriver || mPreviousDriver;
|
||||
}
|
||||
bool Switching();
|
||||
|
||||
GraphDriver* NextDriver()
|
||||
{
|
||||
return mNextDriver;
|
||||
}
|
||||
// Those are simply or setting the associated pointer, but assert that the
|
||||
// lock is held.
|
||||
GraphDriver* NextDriver();
|
||||
GraphDriver* PreviousDriver();
|
||||
void SetNextDriver(GraphDriver* aNextDriver);
|
||||
void SetPreviousDriver(GraphDriver* aPreviousDriver);
|
||||
|
||||
/**
|
||||
* If we are running a real time graph, get the current time stamp to schedule
|
||||
@ -109,19 +149,6 @@ public:
|
||||
return mCurrentTimeStamp;
|
||||
}
|
||||
|
||||
bool IsWaiting() {
|
||||
return mWaitState == WAITSTATE_WAITING_INDEFINITELY ||
|
||||
mWaitState == WAITSTATE_WAITING_FOR_NEXT_ITERATION;
|
||||
}
|
||||
|
||||
bool IsWaitingIndefinitly() {
|
||||
return mWaitState == WAITSTATE_WAITING_INDEFINITELY;
|
||||
}
|
||||
|
||||
GraphTime IterationStart() {
|
||||
return mIterationStart;
|
||||
}
|
||||
|
||||
GraphTime IterationEnd() {
|
||||
return mIterationEnd;
|
||||
}
|
||||
@ -151,13 +178,6 @@ public:
|
||||
void SetGraphTime(GraphDriver* aPreviousDriver,
|
||||
GraphTime aLastSwitchNextIterationStart,
|
||||
GraphTime aLastSwitchNextIterationEnd);
|
||||
|
||||
/**
|
||||
* Call this to indicate that another iteration of the control loop is
|
||||
* required immediately. The monitor must already be held.
|
||||
*/
|
||||
void EnsureImmediateWakeUpLocked();
|
||||
|
||||
/**
|
||||
* Call this to indicate that another iteration of the control loop is
|
||||
* required on its regular schedule. The monitor must not be held.
|
||||
@ -179,12 +199,15 @@ public:
|
||||
protected:
|
||||
GraphTime StateComputedTime() const;
|
||||
|
||||
// Time of the start of this graph iteration.
|
||||
// Time of the start of this graph iteration. This must be accessed while
|
||||
// having the monitor.
|
||||
GraphTime mIterationStart;
|
||||
// Time of the end of this graph iteration.
|
||||
// Time of the end of this graph iteration. This must be accessed while having
|
||||
// the monitor.
|
||||
GraphTime mIterationEnd;
|
||||
// The MediaStreamGraphImpl that owns this driver. This has a lifetime longer
|
||||
// than the driver, and will never be null.
|
||||
// than the driver, and will never be null. Hence, it can be accesed without
|
||||
// monitor.
|
||||
MediaStreamGraphImpl* mGraphImpl;
|
||||
|
||||
// This enum specifies the wait state of the driver.
|
||||
@ -200,15 +223,26 @@ protected:
|
||||
// but it hasn't done so yet
|
||||
WAITSTATE_WAKING_UP
|
||||
};
|
||||
// This must be access with the monitor.
|
||||
WaitState mWaitState;
|
||||
|
||||
// This is used on the main thread (during initialization), and the graph
|
||||
// thread. No monitor needed because we know the graph thread does not run
|
||||
// during the initialization.
|
||||
TimeStamp mCurrentTimeStamp;
|
||||
// This is non-null only when this driver has recently switched from an other
|
||||
// driver, and has not cleaned it up yet (for example because the audio stream
|
||||
// is currently calling the callback during initialization).
|
||||
//
|
||||
// This is written to when changing driver, from the previous driver's thread,
|
||||
// or a thread created for the occasion. This is read each time we need to
|
||||
// check whether we're changing driver (in Switching()), from the graph
|
||||
// thread.
|
||||
// This must be accessed using the {Set,Get}PreviousDriver methods.
|
||||
RefPtr<GraphDriver> mPreviousDriver;
|
||||
// This is non-null only when this driver is going to switch to an other
|
||||
// driver at the end of this iteration.
|
||||
// This must be accessed using the {Set,Get}NextDriver methods.
|
||||
RefPtr<GraphDriver> mNextDriver;
|
||||
virtual ~GraphDriver()
|
||||
{ }
|
||||
@ -264,6 +298,8 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
// Those are only modified (after initialization) on the graph thread. The
|
||||
// graph thread does not run during the initialization.
|
||||
TimeStamp mInitialTimeStamp;
|
||||
TimeStamp mLastTimeStamp;
|
||||
};
|
||||
@ -420,18 +456,22 @@ private:
|
||||
/* The size of this buffer comes from the fact that some audio backends can
|
||||
* call back with a number of frames lower than one block (128 frames), so we
|
||||
* need to keep at most two block in the SpillBuffer, because we always round
|
||||
* up to block boundaries during an iteration. */
|
||||
* up to block boundaries during an iteration.
|
||||
* This is only ever accessed on the audio callback thread. */
|
||||
SpillBuffer<AudioDataValue, WEBAUDIO_BLOCK_SIZE * 2, ChannelCount> mScratchBuffer;
|
||||
/* Wrapper to ensure we write exactly the number of frames we need in the
|
||||
* audio buffer cubeb passes us. */
|
||||
* audio buffer cubeb passes us. This is only ever accessed on the audio
|
||||
* callback thread. */
|
||||
AudioCallbackBufferWrapper<AudioDataValue, ChannelCount> mBuffer;
|
||||
/* cubeb stream for this graph. This is guaranteed to be non-null after Init()
|
||||
* has been called. */
|
||||
* has been called, and is synchronized internaly. */
|
||||
nsAutoRef<cubeb_stream> mAudioStream;
|
||||
/* The sample rate for the aforementionned cubeb stream. */
|
||||
/* The sample rate for the aforementionned cubeb stream. This is set on
|
||||
* initialization and can be read safely afterwards. */
|
||||
uint32_t mSampleRate;
|
||||
/* Approximation of the time between two callbacks. This is used to schedule
|
||||
* video frames. This is in milliseconds. */
|
||||
* video frames. This is in milliseconds. Only even used (after
|
||||
* inizatialization) on the audio callback thread. */
|
||||
uint32_t mIterationDurationMS;
|
||||
/* cubeb_stream_init calls the audio callback to prefill the buffers. The
|
||||
* previous driver has to be kept alive until the audio stream has been
|
||||
@ -459,13 +499,13 @@ private:
|
||||
/* Thread for off-main-thread initialization and
|
||||
* shutdown of the audio stream. */
|
||||
nsCOMPtr<nsIThread> mInitShutdownThread;
|
||||
/* This must be accessed with the graph monitor held. */
|
||||
nsAutoTArray<StreamAndPromiseForOperation, 1> mPromisesForOperation;
|
||||
/* This is set during initialization, and ca be read safely afterwards. */
|
||||
dom::AudioChannel mAudioChannel;
|
||||
/* This is atomic and is set by the audio callback thread. It can be read by
|
||||
* any thread safely. */
|
||||
Atomic<bool> mInCallback;
|
||||
/* A thread has been created to be able to pause and restart the audio thread,
|
||||
* but has not done so yet. This indicates that the callback should return
|
||||
* early */
|
||||
bool mPauseRequested;
|
||||
/**
|
||||
* True if microphone is being used by this process. This is synchronized by
|
||||
* the graph's monitor. */
|
||||
|
@ -361,9 +361,15 @@ MediaStreamGraphImpl::UpdateStreamOrder()
|
||||
}
|
||||
}
|
||||
|
||||
bool switching = false;
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
switching = CurrentDriver()->Switching();
|
||||
}
|
||||
|
||||
if (audioTrackPresent && mRealtime &&
|
||||
!CurrentDriver()->AsAudioCallbackDriver() &&
|
||||
!CurrentDriver()->Switching()) {
|
||||
!switching) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mLifecycleState == LIFECYCLE_RUNNING) {
|
||||
AudioCallbackDriver* driver = new AudioCallbackDriver(this);
|
||||
@ -621,8 +627,15 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
|
||||
audioOutputStream->mLastTickWritten = 0;
|
||||
audioOutputStream->mTrackID = tracks->GetID();
|
||||
|
||||
bool switching = false;
|
||||
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
switching = CurrentDriver()->Switching();
|
||||
}
|
||||
|
||||
if (!CurrentDriver()->AsAudioCallbackDriver() &&
|
||||
!CurrentDriver()->Switching()) {
|
||||
!switching) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mLifecycleState == LIFECYCLE_RUNNING) {
|
||||
AudioCallbackDriver* driver = new AudioCallbackDriver(this);
|
||||
@ -1164,8 +1177,13 @@ MediaStreamGraphImpl::Process()
|
||||
|
||||
// If we are switching away from an AudioCallbackDriver, we don't need the
|
||||
// mixer anymore.
|
||||
bool switching = false;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
switching = CurrentDriver()->Switching();
|
||||
}
|
||||
if (CurrentDriver()->AsAudioCallbackDriver() &&
|
||||
CurrentDriver()->Switching()) {
|
||||
switching) {
|
||||
bool isStarted;
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
@ -3023,6 +3041,16 @@ MediaStreamGraphImpl::ApplyAudioContextOperationImpl(
|
||||
|
||||
SuspendOrResumeStreams(aOperation, aStreams);
|
||||
|
||||
bool switching = false;
|
||||
GraphDriver* nextDriver = nullptr;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
switching = CurrentDriver()->Switching();
|
||||
if (switching) {
|
||||
nextDriver = CurrentDriver()->NextDriver();
|
||||
}
|
||||
}
|
||||
|
||||
// If we have suspended the last AudioContext, and we don't have other
|
||||
// streams that have audio, this graph will automatically switch to a
|
||||
// SystemCallbackDriver, because it can't find a MediaStream that has an audio
|
||||
@ -3032,12 +3060,13 @@ MediaStreamGraphImpl::ApplyAudioContextOperationImpl(
|
||||
if (aOperation == AudioContextOperation::Resume) {
|
||||
if (!CurrentDriver()->AsAudioCallbackDriver()) {
|
||||
AudioCallbackDriver* driver;
|
||||
if (CurrentDriver()->Switching()) {
|
||||
MOZ_ASSERT(CurrentDriver()->NextDriver()->AsAudioCallbackDriver());
|
||||
driver = CurrentDriver()->NextDriver()->AsAudioCallbackDriver();
|
||||
if (switching) {
|
||||
MOZ_ASSERT(nextDriver->AsAudioCallbackDriver());
|
||||
driver = nextDriver->AsAudioCallbackDriver();
|
||||
} else {
|
||||
driver = new AudioCallbackDriver(this);
|
||||
mMixer.AddCallback(driver);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
CurrentDriver()->SwitchAtNextIteration(driver);
|
||||
}
|
||||
driver->EnqueueStreamAndPromiseForOperation(aDestinationStream,
|
||||
@ -3071,19 +3100,20 @@ MediaStreamGraphImpl::ApplyAudioContextOperationImpl(
|
||||
aOperation);
|
||||
|
||||
SystemClockDriver* driver;
|
||||
if (CurrentDriver()->NextDriver()) {
|
||||
MOZ_ASSERT(!CurrentDriver()->NextDriver()->AsAudioCallbackDriver());
|
||||
if (nextDriver) {
|
||||
MOZ_ASSERT(!nextDriver->AsAudioCallbackDriver());
|
||||
} else {
|
||||
driver = new SystemClockDriver(this);
|
||||
mMixer.RemoveCallback(CurrentDriver()->AsAudioCallbackDriver());
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
CurrentDriver()->SwitchAtNextIteration(driver);
|
||||
}
|
||||
// We are closing or suspending an AudioContext, but we just got resumed.
|
||||
// Queue the operation on the next driver so that the ordering is
|
||||
// preserved.
|
||||
} else if (!audioTrackPresent && CurrentDriver()->Switching()) {
|
||||
MOZ_ASSERT(CurrentDriver()->NextDriver()->AsAudioCallbackDriver());
|
||||
CurrentDriver()->NextDriver()->AsAudioCallbackDriver()->
|
||||
} else if (!audioTrackPresent && switching) {
|
||||
MOZ_ASSERT(nextDriver->AsAudioCallbackDriver());
|
||||
nextDriver->AsAudioCallbackDriver()->
|
||||
EnqueueStreamAndPromiseForOperation(aDestinationStream, aPromise,
|
||||
aOperation);
|
||||
} else {
|
||||
|
@ -57,7 +57,7 @@ ChoosePixelFormat(AVCodecContext* aCodecContext, const PixelFormat* aFormats)
|
||||
{
|
||||
FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding.");
|
||||
for (; *aFormats > -1; aFormats++) {
|
||||
if (*aFormats == PIX_FMT_YUV420P) {
|
||||
if (*aFormats == PIX_FMT_YUV420P || *aFormats == PIX_FMT_YUVJ420P) {
|
||||
FFMPEG_LOG("Requesting pixel format YUV420P.");
|
||||
return PIX_FMT_YUV420P;
|
||||
}
|
||||
|
13
dom/media/test/crashtests/1228484.html
Normal file
13
dom/media/test/crashtests/1228484.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
var htmlAudio = new Audio(URL.createObjectURL(new window.MediaSource()));
|
||||
|
||||
(new window.AudioContext("ringer")).createMediaElementSource(htmlAudio);
|
||||
(new window.AudioContext("alarm")).createMediaElementSource(htmlAudio);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
@ -81,6 +81,7 @@ load 1157994.html
|
||||
load 1158427.html
|
||||
load 1185176.html
|
||||
load 1185192.html
|
||||
load 1228484.html
|
||||
load analyser-channels-1.html
|
||||
load audiocontext-double-suspend.html
|
||||
load buffer-source-duration-1.html
|
||||
|
@ -13,8 +13,7 @@ const char* kPermissionTypes[] = {
|
||||
"geo",
|
||||
"desktop-notification",
|
||||
// Alias `push` to `desktop-notification`.
|
||||
"desktop-notification",
|
||||
"midi"
|
||||
"desktop-notification"
|
||||
};
|
||||
|
||||
// `-1` for the last null entry.
|
||||
|
@ -56,7 +56,7 @@ CreatePushPermissionStatus(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (permission.mUserVisible) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -84,8 +84,8 @@ CreatePermissionStatus(JSContext* aCx,
|
||||
case PermissionName::Push:
|
||||
return CreatePushPermissionStatus(aCx, aPermission, aWindow, aRv);
|
||||
|
||||
case PermissionName::Midi:
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unhandled type");
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ const PERMISSIONS = [
|
||||
];
|
||||
|
||||
const UNSUPPORTED_PERMISSIONS = [
|
||||
'midi',
|
||||
'foobarbaz', // Not in spec, for testing only.
|
||||
'midi'
|
||||
];
|
||||
|
||||
function setup() {
|
||||
@ -61,7 +62,10 @@ function checkUnsupportedPermissions() {
|
||||
return Promise.all(UNSUPPORTED_PERMISSIONS.map(name => {
|
||||
return navigator.permissions.query({ name }).then(
|
||||
result => ok(false, `query should not have resolved for '${name}'`),
|
||||
error => ok(true, `query should have rejected for '${name}'`));
|
||||
error => {
|
||||
is(error.name, 'TypeError',
|
||||
`query should have thrown TypeError for '${name}'`);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/dom/PushManager.h"
|
||||
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/unused.h"
|
||||
@ -65,6 +66,26 @@ GetPermissionState(nsIPrincipal* aPrincipal,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionToJSON(PushSubscriptionJSON& aJSON, const nsString& aEndpoint,
|
||||
const nsTArray<uint8_t>& aRawP256dhKey,
|
||||
const nsTArray<uint8_t>& aAuthSecret)
|
||||
{
|
||||
aJSON.mEndpoint.Construct();
|
||||
aJSON.mEndpoint.Value() = aEndpoint;
|
||||
|
||||
aJSON.mKeys.mP256dh.Construct();
|
||||
nsresult rv = Base64URLEncode(aRawP256dhKey.Length(),
|
||||
aRawP256dhKey.Elements(),
|
||||
aJSON.mKeys.mP256dh.Value());
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
aJSON.mKeys.mAuth.Construct();
|
||||
rv = Base64URLEncode(aAuthSecret.Length(), aAuthSecret.Elements(),
|
||||
aJSON.mKeys.mAuth.Value());
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class UnsubscribeResultCallback final : public nsIUnsubscribeResultCallback
|
||||
@ -123,6 +144,12 @@ PushSubscription::Unsubscribe(ErrorResult& aRv)
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void
|
||||
PushSubscription::ToJSON(PushSubscriptionJSON& aJSON)
|
||||
{
|
||||
SubscriptionToJSON(aJSON, mEndpoint, mRawP256dhKey, mAuthSecret);
|
||||
}
|
||||
|
||||
PushSubscription::PushSubscription(nsIGlobalObject* aGlobal,
|
||||
const nsAString& aEndpoint,
|
||||
const nsAString& aScope,
|
||||
@ -507,6 +534,12 @@ WorkerPushSubscription::Unsubscribe(ErrorResult &aRv)
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPushSubscription::ToJSON(PushSubscriptionJSON& aJSON)
|
||||
{
|
||||
SubscriptionToJSON(aJSON, mEndpoint, mRawP256dhKey, mAuthSecret);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerPushSubscription)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(WorkerPushSubscription)
|
||||
|
@ -104,6 +104,9 @@ public:
|
||||
already_AddRefed<Promise>
|
||||
Unsubscribe(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToJSON(PushSubscriptionJSON& aJSON);
|
||||
|
||||
protected:
|
||||
~PushSubscription();
|
||||
|
||||
@ -197,6 +200,9 @@ public:
|
||||
already_AddRefed<Promise>
|
||||
Unsubscribe(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToJSON(PushSubscriptionJSON& aJSON);
|
||||
|
||||
protected:
|
||||
~WorkerPushSubscription();
|
||||
|
||||
|
@ -77,6 +77,47 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
});
|
||||
}
|
||||
|
||||
function base64UrlDecode(s) {
|
||||
s = s.replace(/-/g, '+').replace(/_/g, '/');
|
||||
|
||||
// Replace padding if it was stripped by the sender.
|
||||
// See http://tools.ietf.org/html/rfc4648#section-4
|
||||
switch (s.length % 4) {
|
||||
case 0:
|
||||
break; // No pad chars in this case
|
||||
case 2:
|
||||
s += '==';
|
||||
break; // Two pad chars
|
||||
case 3:
|
||||
s += '=';
|
||||
break; // One pad char
|
||||
default:
|
||||
throw new Error('Illegal base64url string!');
|
||||
}
|
||||
|
||||
// With correct padding restored, apply the standard base64 decoder
|
||||
var decoded = atob(s);
|
||||
|
||||
var array = new Uint8Array(new ArrayBuffer(decoded.length));
|
||||
for (var i = 0; i < decoded.length; i++) {
|
||||
array[i] = decoded.charCodeAt(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
add_task(function* compareJSONSubscription() {
|
||||
var json = pushSubscription.toJSON();
|
||||
is(json.endpoint, pushSubscription.endpoint, "Wrong endpoint");
|
||||
|
||||
["p256dh", "auth"].forEach(keyName => {
|
||||
isDeeply(
|
||||
base64UrlDecode(json.keys[keyName]),
|
||||
new Uint8Array(pushSubscription.getKey(keyName)),
|
||||
"Mismatched Base64-encoded key: " + keyName
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* comparePublicKey() {
|
||||
var data = yield sendRequestToWorker({ type: "publicKey" });
|
||||
var p256dhKey = new Uint8Array(pushSubscription.getKey("p256dh"));
|
||||
|
@ -57,6 +57,17 @@ interface HeapSnapshot {
|
||||
[Throws]
|
||||
any takeCensus(object? options);
|
||||
|
||||
/**
|
||||
* Describe `node` with the specified `breakdown`. See the comment above
|
||||
* `takeCensus` or `js/src/doc/Debugger/Debugger.Memory.md` for detailed
|
||||
* documentation on breakdowns.
|
||||
*
|
||||
* Throws an error when `node` is not the id of a node in the heap snapshot,
|
||||
* or if the breakdown is invalid.
|
||||
*/
|
||||
[Throws]
|
||||
any describeNode(object breakdown, NodeId node);
|
||||
|
||||
/**
|
||||
* Compute the dominator tree for this heap snapshot.
|
||||
*
|
||||
|
@ -10,8 +10,8 @@
|
||||
enum PermissionName {
|
||||
"geolocation",
|
||||
"notifications",
|
||||
"push",
|
||||
"midi"
|
||||
"push"
|
||||
// Unsupported: "midi"
|
||||
};
|
||||
|
||||
dictionary PermissionDescriptor {
|
||||
|
@ -15,6 +15,18 @@ enum PushEncryptionKeyName
|
||||
"auth"
|
||||
};
|
||||
|
||||
dictionary PushSubscriptionKeys
|
||||
{
|
||||
ByteString p256dh;
|
||||
ByteString auth;
|
||||
};
|
||||
|
||||
dictionary PushSubscriptionJSON
|
||||
{
|
||||
USVString endpoint;
|
||||
PushSubscriptionKeys keys;
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled",
|
||||
ChromeConstructor(DOMString pushEndpoint, DOMString scope,
|
||||
ArrayBuffer? key, ArrayBuffer? authSecret)]
|
||||
@ -24,7 +36,9 @@ interface PushSubscription
|
||||
ArrayBuffer? getKey(PushEncryptionKeyName name);
|
||||
[Throws, UseCounter]
|
||||
Promise<boolean> unsubscribe();
|
||||
jsonifier;
|
||||
|
||||
// Implements the custom serializer specified in Push API, section 9.
|
||||
PushSubscriptionJSON toJSON();
|
||||
|
||||
// Used to set the principal from the JS implemented PushManager.
|
||||
[Exposed=Window,ChromeOnly]
|
||||
|
@ -946,22 +946,21 @@ class ServiceWorkerJobBase : public ServiceWorkerJob
|
||||
public:
|
||||
ServiceWorkerJobBase(ServiceWorkerJobQueue* aQueue,
|
||||
ServiceWorkerJob::Type aJobType,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback)
|
||||
: ServiceWorkerJobBase(aQueue, aJobType, aCallback, nullptr, nullptr)
|
||||
{ }
|
||||
|
||||
ServiceWorkerJobBase(ServiceWorkerJobQueue* aQueue,
|
||||
ServiceWorkerJob::Type aJobType,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
const nsACString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
ServiceWorkerRegistrationInfo* aRegistration,
|
||||
ServiceWorkerInfo* aServiceWorkerInfo)
|
||||
: ServiceWorkerJob(aQueue, aJobType)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mScope(aScope)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mCallback(aCallback)
|
||||
, mCanceled(false)
|
||||
, mRegistration(aRegistration)
|
||||
, mUpdateAndInstallInfo(aServiceWorkerInfo)
|
||||
, mCanceled(false)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
}
|
||||
|
||||
void
|
||||
@ -972,14 +971,49 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
const nsCString mScope;
|
||||
const nsCString mScriptSpec;
|
||||
RefPtr<ServiceWorkerUpdateFinishCallback> mCallback;
|
||||
bool mCanceled;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
RefPtr<ServiceWorkerInfo> mUpdateAndInstallInfo;
|
||||
bool mCanceled;
|
||||
|
||||
~ServiceWorkerJobBase()
|
||||
{ }
|
||||
|
||||
// Ensure that mRegistration is set for the job. Also, if mRegistration was
|
||||
// already set, ensure that a new registration object has not replaced it in
|
||||
// the ServiceWorkerManager. This can happen when jobs race such that the
|
||||
// registration is cleared and recreated while an update job is executing.
|
||||
nsresult
|
||||
EnsureAndVerifyRegistration()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (NS_WARN_IF(!swm)) {
|
||||
mRegistration = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
swm->GetRegistration(mPrincipal, mScope);
|
||||
|
||||
if (NS_WARN_IF(!registration)) {
|
||||
mRegistration = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(mRegistration && registration != mRegistration)) {
|
||||
mRegistration = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
mRegistration = registration.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Succeed()
|
||||
{
|
||||
@ -990,25 +1024,6 @@ protected:
|
||||
mCallback = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Base type for jobs that work with a specific service worker script.
|
||||
class ServiceWorkerScriptJobBase : public ServiceWorkerJobBase
|
||||
{
|
||||
protected:
|
||||
const nsCString mScriptSpec;
|
||||
|
||||
ServiceWorkerScriptJobBase(ServiceWorkerJobQueue* aQueue,
|
||||
ServiceWorkerJob::Type aJobType,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
ServiceWorkerRegistrationInfo* aRegistration,
|
||||
ServiceWorkerInfo* aServiceWorkerInfo,
|
||||
const nsACString& aScriptSpec)
|
||||
: ServiceWorkerJobBase(aQueue, aJobType, aCallback, aRegistration,
|
||||
aServiceWorkerInfo)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
{
|
||||
}
|
||||
|
||||
// This MUST only be called when the job is still performing actions related
|
||||
// to registration or update. After the spec resolves the update promise, use
|
||||
@ -1018,7 +1033,6 @@ protected:
|
||||
FailWithErrorResult(ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
// With cancellation support, we may only be running with one reference
|
||||
// from another object like a stream loader or something.
|
||||
@ -1036,7 +1050,7 @@ protected:
|
||||
aRv.SuppressException();
|
||||
|
||||
NS_ConvertUTF8toUTF16 scriptSpec(mScriptSpec);
|
||||
NS_ConvertUTF8toUTF16 scope(mRegistration->mScope);
|
||||
NS_ConvertUTF8toUTF16 scope(mScope);
|
||||
|
||||
// Throw the type error with a generic error message.
|
||||
aRv.ThrowTypeError<MSG_SW_INSTALL_ERROR>(scriptSpec, scope);
|
||||
@ -1050,8 +1064,14 @@ protected:
|
||||
aRv.SuppressException();
|
||||
|
||||
mUpdateAndInstallInfo = nullptr;
|
||||
|
||||
if (!mRegistration) {
|
||||
Done(origStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRegistration->mInstallingWorker) {
|
||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mRegistration->mPrincipal,
|
||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
||||
mRegistration->mInstallingWorker->CacheName());
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to purge the installing worker cache.");
|
||||
@ -1073,21 +1093,27 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class ServiceWorkerInstallJob final : public ServiceWorkerScriptJobBase
|
||||
class ServiceWorkerInstallJob final : public ServiceWorkerJobBase
|
||||
{
|
||||
friend class ContinueInstallTask;
|
||||
|
||||
public:
|
||||
enum InstallType {
|
||||
UpdateSameScript,
|
||||
OverwriteScript
|
||||
};
|
||||
|
||||
ServiceWorkerInstallJob(ServiceWorkerJobQueue* aQueue,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
const nsACString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
ServiceWorkerRegistrationInfo* aRegistration,
|
||||
ServiceWorkerInfo* aServiceWorkerInfo,
|
||||
const nsACString& aScriptSpec)
|
||||
: ServiceWorkerScriptJobBase(aQueue, Type::InstallJob, aCallback,
|
||||
aRegistration, aServiceWorkerInfo,
|
||||
aScriptSpec)
|
||||
InstallType aType)
|
||||
: ServiceWorkerJobBase(aQueue, Type::InstallJob, aPrincipal, aScope,
|
||||
aScriptSpec, aCallback, aServiceWorkerInfo)
|
||||
, mType(aType)
|
||||
{
|
||||
MOZ_ASSERT(aRegistration);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1103,10 +1129,25 @@ public:
|
||||
Install()
|
||||
{
|
||||
RefPtr<ServiceWorkerJob> kungFuDeathGrip = this;
|
||||
|
||||
if (mCanceled) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
// If we are trying to install an update for an existing script, then
|
||||
// make sure we don't overwrite a recent script change or resurrect a
|
||||
// dead registration.
|
||||
if (mType == UpdateSameScript) {
|
||||
RefPtr<ServiceWorkerInfo> newest = mRegistration->Newest();
|
||||
if (!newest || !mScriptSpec.Equals(newest->ScriptSpec())) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
// Begin [[Install]] atomic step 3.
|
||||
if (mRegistration->mInstallingWorker) {
|
||||
@ -1148,8 +1189,8 @@ public:
|
||||
// which sends the install event to the worker.
|
||||
ServiceWorkerPrivate* workerPrivate =
|
||||
mRegistration->mInstallingWorker->WorkerPrivate();
|
||||
nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("install"),
|
||||
callback, failRunnable);
|
||||
rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("install"),
|
||||
callback, failRunnable);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
ContinueAfterInstallEvent(false /* aSuccess */);
|
||||
@ -1163,6 +1204,11 @@ public:
|
||||
return Done(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
if (!mRegistration->mInstallingWorker) {
|
||||
NS_WARNING("mInstallingWorker was null.");
|
||||
return Done(NS_ERROR_DOM_ABORT_ERR);
|
||||
@ -1196,6 +1242,7 @@ public:
|
||||
mRegistration->mWaitingWorker = mRegistration->mInstallingWorker.forget();
|
||||
mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
|
||||
mRegistration->NotifyListenersOnChange();
|
||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
||||
WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
|
||||
|
||||
@ -1208,15 +1255,16 @@ public:
|
||||
// Activate() is invoked out of band of atomic.
|
||||
mRegistration->TryToActivate();
|
||||
}
|
||||
|
||||
private:
|
||||
const InstallType mType;
|
||||
};
|
||||
|
||||
class ServiceWorkerRegisterJob final : public ServiceWorkerScriptJobBase,
|
||||
class ServiceWorkerRegisterJob final : public ServiceWorkerJobBase,
|
||||
public serviceWorkerScriptCache::CompareCallback
|
||||
{
|
||||
friend class ContinueUpdateRunnable;
|
||||
|
||||
nsCString mScope;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
~ServiceWorkerRegisterJob()
|
||||
@ -1227,15 +1275,13 @@ public:
|
||||
|
||||
// [[Register]]
|
||||
ServiceWorkerRegisterJob(ServiceWorkerJobQueue* aQueue,
|
||||
const nsCString& aScope,
|
||||
const nsCString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
const nsACString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
nsILoadGroup* aLoadGroup)
|
||||
: ServiceWorkerScriptJobBase(aQueue, Type::RegisterJob, aCallback, nullptr,
|
||||
nullptr, aScriptSpec)
|
||||
, mScope(aScope)
|
||||
, mPrincipal(aPrincipal)
|
||||
: ServiceWorkerJobBase(aQueue, Type::RegisterJob, aPrincipal, aScope,
|
||||
aScriptSpec, aCallback, nullptr)
|
||||
, mLoadGroup(aLoadGroup)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
@ -1245,11 +1291,12 @@ public:
|
||||
|
||||
// [[Update]]
|
||||
ServiceWorkerRegisterJob(ServiceWorkerJobQueue* aQueue,
|
||||
ServiceWorkerRegistrationInfo* aRegistration,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
const nsACString& aScriptSpec)
|
||||
: ServiceWorkerScriptJobBase(aQueue, Type::UpdateJob, aCallback,
|
||||
aRegistration, nullptr, aScriptSpec)
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope,
|
||||
const nsACString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback)
|
||||
: ServiceWorkerJobBase(aQueue, Type::UpdateJob, aPrincipal, aScope,
|
||||
aScriptSpec, aCallback, nullptr)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
@ -1269,13 +1316,13 @@ public:
|
||||
}
|
||||
|
||||
if (mJobType == RegisterJob) {
|
||||
MOZ_ASSERT(!mRegistration);
|
||||
mRegistration = swm->GetRegistration(mPrincipal, mScope);
|
||||
|
||||
if (mRegistration) {
|
||||
mRegistration->mPendingUninstall = false;
|
||||
RefPtr<ServiceWorkerInfo> newest = mRegistration->Newest();
|
||||
if (newest && mScriptSpec.Equals(newest->ScriptSpec())) {
|
||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
||||
Succeed();
|
||||
|
||||
// Done() must always be called async from Start()
|
||||
@ -1291,15 +1338,22 @@ public:
|
||||
} else {
|
||||
mRegistration = swm->CreateNewRegistration(mScope, mPrincipal);
|
||||
}
|
||||
|
||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
||||
} else {
|
||||
MOZ_ASSERT(mJobType == UpdateJob);
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// Do nothing here, but since mRegistration is nullptr we will
|
||||
// trigger the async Fail() call below.
|
||||
MOZ_ASSERT(!mRegistration);
|
||||
}
|
||||
|
||||
// If a different script spec has been registered between when this update
|
||||
// was scheduled and it running now, then simply abort.
|
||||
RefPtr<ServiceWorkerInfo> newest = mRegistration->Newest();
|
||||
if (newest && !mScriptSpec.Equals(newest->ScriptSpec())) {
|
||||
RefPtr<ServiceWorkerInfo> newest = mRegistration ? mRegistration->Newest()
|
||||
: nullptr;
|
||||
if (!mRegistration ||
|
||||
(newest && !mScriptSpec.Equals(newest->ScriptSpec()))) {
|
||||
|
||||
// Done() must always be called async from Start()
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
@ -1322,6 +1376,7 @@ public:
|
||||
const nsACString& aMaxScope) override
|
||||
{
|
||||
RefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
|
||||
|
||||
if (NS_WARN_IF(mCanceled)) {
|
||||
Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
return;
|
||||
@ -1332,6 +1387,11 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
if (aInCacheAndEqual) {
|
||||
Succeed();
|
||||
Done(NS_OK);
|
||||
@ -1344,7 +1404,7 @@ public:
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
|
||||
nsCOMPtr<nsIURI> scriptURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scriptURI), mScriptSpec);
|
||||
rv = NS_NewURI(getter_AddRefs(scriptURI), mScriptSpec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Fail(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
@ -1417,7 +1477,12 @@ private:
|
||||
ContinueInstall(bool aScriptEvaluationResult)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
mRegistration->mUpdating = false;
|
||||
|
||||
RefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
|
||||
@ -1434,9 +1499,22 @@ private:
|
||||
return FailWithErrorResult(error);
|
||||
}
|
||||
|
||||
// For updates we want to make sure our install job does not end up
|
||||
// changing the script for the registration. Since a registration
|
||||
// script change can be queued in an install job, we can not
|
||||
// conclusively verify that the update install should proceed here.
|
||||
// Instead, we have to pass a flag into our install job indicating
|
||||
// if a script change is allowed or not. This can then be used to
|
||||
// check the current script after all previous install jobs have been
|
||||
// flushed.
|
||||
ServiceWorkerInstallJob::InstallType installType =
|
||||
mJobType == UpdateJob ? ServiceWorkerInstallJob::UpdateSameScript
|
||||
: ServiceWorkerInstallJob::OverwriteScript;
|
||||
|
||||
RefPtr<ServiceWorkerInstallJob> job =
|
||||
new ServiceWorkerInstallJob(mQueue, mCallback, mRegistration,
|
||||
mUpdateAndInstallInfo, mScriptSpec);
|
||||
new ServiceWorkerInstallJob(mQueue, mPrincipal, mScope, mScriptSpec,
|
||||
mCallback, mUpdateAndInstallInfo,
|
||||
installType);
|
||||
mQueue->Append(job);
|
||||
Done(NS_OK);
|
||||
}
|
||||
@ -1463,10 +1541,16 @@ private:
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
RefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
|
||||
|
||||
if (mCanceled) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = EnsureAndVerifyRegistration();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
if (mRegistration->mInstallingWorker) {
|
||||
mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||
mRegistration->mInstallingWorker->WorkerPrivate()->TerminateWorker();
|
||||
@ -1483,10 +1567,9 @@ private:
|
||||
cacheName = workerInfo->CacheName();
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
serviceWorkerScriptCache::Compare(mRegistration, mRegistration->mPrincipal, cacheName,
|
||||
NS_ConvertUTF8toUTF16(mScriptSpec), this,
|
||||
mLoadGroup);
|
||||
rv = serviceWorkerScriptCache::Compare(mRegistration, mPrincipal, cacheName,
|
||||
NS_ConvertUTF8toUTF16(mScriptSpec),
|
||||
this, mLoadGroup);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(rv);
|
||||
}
|
||||
@ -1735,7 +1818,8 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
RefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, cleanedScope, spec, cb, documentPrincipal, loadGroup);
|
||||
new ServiceWorkerRegisterJob(queue, documentPrincipal, cleanedScope, spec,
|
||||
cb, loadGroup);
|
||||
queue->Append(job);
|
||||
|
||||
AssertIsOnMainThread();
|
||||
@ -3712,10 +3796,23 @@ ServiceWorkerManager::NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegist
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::SoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
ServiceWorkerManager::SoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aScope)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> scopeURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), aScope);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
BasePrincipal::CreateCodebasePrincipal(scopeURI, aOriginAttributes);
|
||||
if (NS_WARN_IF(!principal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString scopeKey;
|
||||
aOriginAttributes.CreateSuffix(scopeKey);
|
||||
|
||||
@ -3752,8 +3849,8 @@ ServiceWorkerManager::SoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
MOZ_ASSERT(queue);
|
||||
|
||||
RefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, registration, nullptr,
|
||||
newest->ScriptSpec());
|
||||
new ServiceWorkerRegisterJob(queue, principal, registration->mScope,
|
||||
newest->ScriptSpec(), nullptr);
|
||||
queue->Append(job);
|
||||
}
|
||||
}
|
||||
@ -3804,8 +3901,8 @@ ServiceWorkerManager::Update(nsIPrincipal* aPrincipal,
|
||||
// "Invoke Update algorithm, or its equivalent, with client, registration as
|
||||
// its argument."
|
||||
RefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, registration, aCallback,
|
||||
newest->ScriptSpec());
|
||||
new ServiceWorkerRegisterJob(queue, aPrincipal, registration->mScope,
|
||||
newest->ScriptSpec(), aCallback);
|
||||
queue->Append(job);
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ public:
|
||||
ServiceWorkerUpdateFinishCallback* aCallback);
|
||||
|
||||
void
|
||||
SoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
SoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aScope);
|
||||
|
||||
void
|
||||
|
@ -12,11 +12,7 @@
|
||||
#include "FilterNodeSoftware.h"
|
||||
#include "HelpersSkia.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
#include "skia/include/gpu/SkGpuDevice.h"
|
||||
#include "skia/include/gpu/gl/GrGLInterface.h"
|
||||
#endif
|
||||
|
||||
#include "skia/include/core/SkSurface.h"
|
||||
#include "skia/include/core/SkTypeface.h"
|
||||
#include "skia/include/effects/SkGradientShader.h"
|
||||
#include "skia/include/core/SkColorFilter.h"
|
||||
@ -149,29 +145,32 @@ bool
|
||||
DrawTargetSkia::LockBits(uint8_t** aData, IntSize* aSize,
|
||||
int32_t* aStride, SurfaceFormat* aFormat)
|
||||
{
|
||||
const SkBitmap &bitmap = mCanvas->getDevice()->accessBitmap(false);
|
||||
if (!bitmap.lockPixelsAreWritable()) {
|
||||
/* Test if the canvas' device has accessible pixels first, as actually
|
||||
* accessing the pixels may trigger side-effects, even if it fails.
|
||||
*/
|
||||
if (!mCanvas->peekPixels(nullptr, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkImageInfo info;
|
||||
size_t rowBytes;
|
||||
void* pixels = mCanvas->accessTopLayerPixels(&info, &rowBytes);
|
||||
if (!pixels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MarkChanged();
|
||||
|
||||
bitmap.lockPixels();
|
||||
*aData = reinterpret_cast<uint8_t*>(bitmap.getPixels());
|
||||
*aSize = IntSize(bitmap.width(), bitmap.height());
|
||||
*aStride = int32_t(bitmap.rowBytes());
|
||||
*aFormat = SkiaColorTypeToGfxFormat(bitmap.colorType());
|
||||
*aData = reinterpret_cast<uint8_t*>(pixels);
|
||||
*aSize = IntSize(info.width(), info.height());
|
||||
*aStride = int32_t(rowBytes);
|
||||
*aFormat = SkiaColorTypeToGfxFormat(info.colorType());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::ReleaseBits(uint8_t* aData)
|
||||
{
|
||||
const SkBitmap &bitmap = mCanvas->getDevice()->accessBitmap(false);
|
||||
MOZ_ASSERT(bitmap.lockPixelsAreWritable());
|
||||
|
||||
bitmap.unlockPixels();
|
||||
bitmap.notifyPixelsChanged();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -266,7 +265,7 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, TempBitmap& aTmpBitmap
|
||||
SkSafeUnref(shader);
|
||||
SkSafeUnref(aPaint.setShader(matrixShader));
|
||||
if (pat.mFilter == Filter::POINT) {
|
||||
aPaint.setFilterLevel(SkPaint::kNone_FilterLevel);
|
||||
aPaint.setFilterQuality(kNone_SkFilterQuality);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -333,7 +332,7 @@ struct AutoPaintSetup {
|
||||
mPaint.setAlpha(ColorFloatToByte(aOptions.mAlpha));
|
||||
mAlpha = aOptions.mAlpha;
|
||||
}
|
||||
mPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
mPaint.setFilterQuality(kLow_SkFilterQuality);
|
||||
}
|
||||
|
||||
// TODO: Maybe add an operator overload to access this easier?
|
||||
@ -381,10 +380,10 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
||||
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, &aDest);
|
||||
if (aSurfOptions.mFilter == Filter::POINT) {
|
||||
paint.mPaint.setFilterLevel(SkPaint::kNone_FilterLevel);
|
||||
paint.mPaint.setFilterQuality(kNone_SkFilterQuality);
|
||||
}
|
||||
|
||||
mCanvas->drawBitmapRectToRect(bitmap.mBitmap, &sourceRect, destRect, &paint.mPaint);
|
||||
mCanvas->drawBitmapRect(bitmap.mBitmap, sourceRect, destRect, &paint.mPaint);
|
||||
}
|
||||
|
||||
DrawTargetType
|
||||
@ -797,9 +796,7 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
||||
SkBitmap bm(bitmap.mBitmap);
|
||||
bm.lockPixels();
|
||||
if (bm.getPixels()) {
|
||||
SkImageInfo info = bm.info();
|
||||
info.fWidth = aSourceRect.width;
|
||||
info.fHeight = aSourceRect.height;
|
||||
SkImageInfo info = bm.info().makeWH(aSourceRect.width, aSourceRect.height);
|
||||
uint8_t* pixels = static_cast<uint8_t*>(bm.getPixels());
|
||||
// adjust pixels for the source offset
|
||||
pixels += aSourceRect.x + aSourceRect.y*bm.rowBytes();
|
||||
@ -831,7 +828,7 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
||||
clearPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
mCanvas->drawPaint(clearPaint);
|
||||
}
|
||||
mCanvas->drawBitmapRect(bitmap.mBitmap, &source, dest, &paint);
|
||||
mCanvas->drawBitmapRect(bitmap.mBitmap, source, dest, &paint);
|
||||
mCanvas->restore();
|
||||
}
|
||||
|
||||
@ -854,7 +851,7 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.setInfo(skiInfo, stride);
|
||||
if (!bitmap.allocPixels()) {
|
||||
if (!bitmap.tryAllocPixels()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -883,24 +880,28 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
|
||||
mSize = aSize;
|
||||
mFormat = aFormat;
|
||||
|
||||
GrTextureDesc targetDescriptor;
|
||||
GrSurfaceDesc targetDescriptor;
|
||||
|
||||
targetDescriptor.fFlags = kRenderTarget_GrTextureFlagBit;
|
||||
targetDescriptor.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
targetDescriptor.fWidth = mSize.width;
|
||||
targetDescriptor.fHeight = mSize.height;
|
||||
targetDescriptor.fConfig = GfxFormatToGrConfig(mFormat);
|
||||
targetDescriptor.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
targetDescriptor.fSampleCnt = 0;
|
||||
|
||||
SkAutoTUnref<GrTexture> skiaTexture(mGrContext->createUncachedTexture(targetDescriptor, NULL, 0));
|
||||
SkAutoTUnref<GrTexture> skiaTexture(mGrContext->textureProvider()->createTexture(targetDescriptor, SkSurface::kNo_Budgeted, nullptr, 0));
|
||||
if (!skiaTexture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTexture = (uint32_t)skiaTexture->getTextureHandle();
|
||||
SkAutoTUnref<SkSurface> gpuSurface(SkSurface::NewRenderTargetDirect(skiaTexture->asRenderTarget()));
|
||||
if (!gpuSurface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), skiaTexture->asRenderTarget()));
|
||||
mCanvas.adopt(new SkCanvas(device.get()));
|
||||
mTexture = reinterpret_cast<GrGLTextureInfo *>(skiaTexture->getTextureHandle())->fID;
|
||||
|
||||
mCanvas = gpuSurface->getCanvas();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ private:
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
RefPtrSkia<GrContext> mGrContext;
|
||||
uint32_t mTexture;
|
||||
GrGLuint mTexture;
|
||||
#endif
|
||||
|
||||
IntSize mSize;
|
||||
|
@ -41,20 +41,20 @@ SkTypeface* ScaledFontCairo::GetSkTypeface()
|
||||
{
|
||||
if (!mTypeface) {
|
||||
cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(mScaledFont);
|
||||
MOZ_ASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
FT_Face face = cairo_ft_scaled_font_lock_face(mScaledFont);
|
||||
|
||||
int style = SkTypeface::kNormal;
|
||||
|
||||
if (face->style_flags & FT_STYLE_FLAG_ITALIC)
|
||||
style |= SkTypeface::kItalic;
|
||||
|
||||
if (face->style_flags & FT_STYLE_FLAG_BOLD)
|
||||
style |= SkTypeface::kBold;
|
||||
SkFontStyle style(face->style_flags & FT_STYLE_FLAG_BOLD ?
|
||||
SkFontStyle::kBold_Weight : SkFontStyle::kNormal_Weight,
|
||||
SkFontStyle::kNormal_Width,
|
||||
face->style_flags & FT_STYLE_FLAG_ITALIC ?
|
||||
SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
|
||||
|
||||
bool isFixedWidth = face->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
|
||||
cairo_ft_scaled_font_unlock_face(mScaledFont);
|
||||
|
||||
mTypeface = SkCreateTypefaceFromCairoFont(fontFace, (SkTypeface::Style)style, isFixedWidth);
|
||||
mTypeface = SkCreateTypefaceFromCairoFont(fontFace, style, isFixedWidth);
|
||||
}
|
||||
|
||||
return mTypeface;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "DataSurfaceHelpers.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
#include "GLDefs.h"
|
||||
#include "skia/include/gpu/SkGrPixelRef.h"
|
||||
#endif
|
||||
|
||||
@ -50,13 +51,11 @@ SourceSurfaceSkia::InitFromCanvas(SkCanvas* aCanvas,
|
||||
SurfaceFormat aFormat,
|
||||
DrawTargetSkia* aOwner)
|
||||
{
|
||||
SkISize size = aCanvas->getDeviceSize();
|
||||
|
||||
mBitmap = (SkBitmap)aCanvas->getDevice()->accessBitmap(false);
|
||||
mBitmap = aCanvas->getDevice()->accessBitmap(false);
|
||||
|
||||
mFormat = aFormat;
|
||||
|
||||
mSize = IntSize(size.fWidth, size.fHeight);
|
||||
mSize = IntSize(mBitmap.width(), mBitmap.height());
|
||||
mStride = mBitmap.rowBytes();
|
||||
mDrawTarget = aOwner;
|
||||
|
||||
@ -84,10 +83,6 @@ SourceSurfaceSkia::InitFromData(unsigned char* aData,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aFormat == SurfaceFormat::B8G8R8X8) {
|
||||
mBitmap.setAlphaType(kIgnore_SkAlphaType);
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
mFormat = aFormat;
|
||||
mStride = mBitmap.rowBytes();
|
||||
@ -109,11 +104,15 @@ SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner,
|
||||
skiaTexGlue.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
skiaTexGlue.fConfig = GfxFormatToGrConfig(aFormat);
|
||||
skiaTexGlue.fSampleCnt = 0;
|
||||
skiaTexGlue.fTextureHandle = aTexture;
|
||||
|
||||
GrTexture *skiaTexture = aOwner->mGrContext->wrapBackendTexture(skiaTexGlue);
|
||||
GrGLTextureInfo texInfo;
|
||||
texInfo.fTarget = LOCAL_GL_TEXTURE_2D;
|
||||
texInfo.fID = aTexture;
|
||||
skiaTexGlue.fTextureHandle = reinterpret_cast<GrBackendObject>(&texInfo);
|
||||
|
||||
GrTexture *skiaTexture = aOwner->mGrContext->textureProvider()->wrapBackendTexture(skiaTexGlue);
|
||||
SkImageInfo imgInfo = SkImageInfo::Make(aSize.width, aSize.height, GfxFormatToSkiaColorType(aFormat), kOpaque_SkAlphaType);
|
||||
SkGrPixelRef *texRef = new SkGrPixelRef(imgInfo, skiaTexture, false);
|
||||
SkGrPixelRef *texRef = new SkGrPixelRef(imgInfo, skiaTexture);
|
||||
mBitmap.setInfo(imgInfo);
|
||||
mBitmap.setPixelRef(texRef);
|
||||
mFormat = aFormat;
|
||||
|
@ -89,6 +89,11 @@ GrGLvoid glBlendColor_mozilla(GrGLclampf red, GrGLclampf green, GrGLclampf blue,
|
||||
return sGLContext.get()->fBlendColor(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
GrGLvoid glBlendEquation_mozilla(GrGLenum mode)
|
||||
{
|
||||
return sGLContext.get()->fBlendEquation(mode);
|
||||
}
|
||||
|
||||
GrGLvoid glBlendFunc_mozilla(GrGLenum sfactor, GrGLenum dfactor)
|
||||
{
|
||||
return sGLContext.get()->fBlendFunc(sfactor, dfactor);
|
||||
@ -315,6 +320,11 @@ GrGLvoid glGetShaderiv_mozilla(GrGLuint shader, GrGLenum pname, GrGLint* params)
|
||||
return sGLContext.get()->fGetShaderiv(shader, pname, params);
|
||||
}
|
||||
|
||||
GrGLvoid glGetShaderPrecisionFormat_mozilla(GrGLenum shadertype, GrGLenum precisiontype, GLint *range, GLint *precision)
|
||||
{
|
||||
return sGLContext.get()->fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
|
||||
}
|
||||
|
||||
const GLubyte* glGetString_mozilla(GrGLenum name)
|
||||
{
|
||||
// GLContext only exposes a OpenGL 2.0 style API, so we have to intercept a bunch
|
||||
@ -357,6 +367,12 @@ const GLubyte* glGetString_mozilla(GrGLenum name)
|
||||
if (sGLContext.get()->IsSupported(GLFeature::standard_derivatives)) {
|
||||
strcat(extensionsString, "GL_OES_standard_derivatives ");
|
||||
}
|
||||
} else {
|
||||
if (sGLContext.get()->IsSupported(GLFeature::framebuffer_object)) {
|
||||
strcat(extensionsString, "GL_ARB_framebuffer_object ");
|
||||
} else if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_framebuffer_object)) {
|
||||
strcat(extensionsString, "GL_EXT_framebuffer_object ");
|
||||
}
|
||||
}
|
||||
|
||||
if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) {
|
||||
@ -581,6 +597,21 @@ GrGLvoid glUseProgram_mozilla(GrGLuint program)
|
||||
return sGLContext.get()->fUseProgram(program);
|
||||
}
|
||||
|
||||
GrGLvoid glVertexAttrib1f_mozilla(GrGLuint index, GrGLfloat value)
|
||||
{
|
||||
return sGLContext.get()->fVertexAttrib1f(index, value);
|
||||
}
|
||||
|
||||
GrGLvoid glVertexAttrib2fv_mozilla(GrGLuint index, const GrGLfloat* values)
|
||||
{
|
||||
return sGLContext.get()->fVertexAttrib2fv(index, values);
|
||||
}
|
||||
|
||||
GrGLvoid glVertexAttrib3fv_mozilla(GrGLuint index, const GrGLfloat* values)
|
||||
{
|
||||
return sGLContext.get()->fVertexAttrib3fv(index, values);
|
||||
}
|
||||
|
||||
GrGLvoid glVertexAttrib4fv_mozilla(GrGLuint index, const GrGLfloat* values)
|
||||
{
|
||||
return sGLContext.get()->fVertexAttrib4fv(index, values);
|
||||
@ -767,6 +798,7 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
i->fFunctions.fBindTexture = glBindTexture_mozilla;
|
||||
i->fFunctions.fBlendFunc = glBlendFunc_mozilla;
|
||||
i->fFunctions.fBlendColor = glBlendColor_mozilla;
|
||||
i->fFunctions.fBlendEquation = glBlendEquation_mozilla;
|
||||
i->fFunctions.fBufferData = glBufferData_mozilla;
|
||||
i->fFunctions.fBufferSubData = glBufferSubData_mozilla;
|
||||
i->fFunctions.fCheckFramebufferStatus = glCheckFramebufferStatus_mozilla;
|
||||
@ -811,6 +843,7 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
i->fFunctions.fGetRenderbufferParameteriv = glGetRenderbufferParameteriv_mozilla;
|
||||
i->fFunctions.fGetShaderInfoLog = glGetShaderInfoLog_mozilla;
|
||||
i->fFunctions.fGetShaderiv = glGetShaderiv_mozilla;
|
||||
i->fFunctions.fGetShaderPrecisionFormat = glGetShaderPrecisionFormat_mozilla;
|
||||
i->fFunctions.fGetString = glGetString_mozilla;
|
||||
i->fFunctions.fGetUniformLocation = glGetUniformLocation_mozilla;
|
||||
i->fFunctions.fLineWidth = glLineWidth_mozilla;
|
||||
@ -847,6 +880,9 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
i->fFunctions.fUniformMatrix3fv = glUniformMatrix3fv_mozilla;
|
||||
i->fFunctions.fUniformMatrix4fv = glUniformMatrix4fv_mozilla;
|
||||
i->fFunctions.fUseProgram = glUseProgram_mozilla;
|
||||
i->fFunctions.fVertexAttrib1f = glVertexAttrib1f_mozilla;
|
||||
i->fFunctions.fVertexAttrib2fv = glVertexAttrib2fv_mozilla;
|
||||
i->fFunctions.fVertexAttrib3fv = glVertexAttrib3fv_mozilla;
|
||||
i->fFunctions.fVertexAttrib4fv = glVertexAttrib4fv_mozilla;
|
||||
i->fFunctions.fVertexAttribPointer = glVertexAttribPointer_mozilla;
|
||||
i->fFunctions.fViewport = glViewport_mozilla;
|
||||
|
@ -254,9 +254,9 @@ Transform(DataSourceSurface* aDest,
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
destCanvas.drawBitmapRect(src, destRect, &paint);
|
||||
}
|
||||
#else
|
||||
static pixman_transform
|
||||
|
@ -742,9 +742,9 @@ Transform(const gfxImageSurface* aDest,
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
destCanvas.drawBitmapRect(src, destRect, &paint);
|
||||
}
|
||||
#else
|
||||
static pixman_transform
|
||||
|
@ -25,34 +25,12 @@ header = """
|
||||
|
||||
footer = """
|
||||
|
||||
# can we find a better way of dealing with asm sources?
|
||||
|
||||
# left out of UNIFIED_SOURCES for now; that's not C++ anyway, nothing else to unify it with
|
||||
#XXX: doesn't build with Apple's assembler
|
||||
if not CONFIG['INTEL_ARCHITECTURE'] and CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['OS_TARGET'] != 'Darwin':
|
||||
SOURCES += [
|
||||
'skia/src/opts/memset.arm.S',
|
||||
]
|
||||
if CONFIG['BUILD_ARM_NEON']:
|
||||
SOURCES += [
|
||||
'skia/src/opts/memset16_neon.S',
|
||||
'skia/src/opts/memset32_neon.S',
|
||||
]
|
||||
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['GNU_CC'] and CONFIG['OS_ARCH'] != 'WINNT':
|
||||
if CONFIG['CPU_ARCH'] == 'x86_64':
|
||||
SOURCES += [
|
||||
'skia/src/opts/SkBlitRow_opts_SSE4_x64_asm.S',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'skia/src/opts/SkBlitRow_opts_SSE4_asm.S',
|
||||
]
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'gkmedias'
|
||||
LOCAL_INCLUDES += [
|
||||
'skia/include/c',
|
||||
'skia/include/config',
|
||||
'skia/include/core',
|
||||
'skia/include/effects',
|
||||
@ -61,6 +39,7 @@ LOCAL_INCLUDES += [
|
||||
'skia/include/pathops',
|
||||
'skia/include/pipe',
|
||||
'skia/include/ports',
|
||||
'skia/include/private',
|
||||
'skia/include/utils',
|
||||
'skia/include/utils/mac',
|
||||
'skia/include/utils/win',
|
||||
@ -78,12 +57,6 @@ LOCAL_INCLUDES += [
|
||||
'skia/src/utils/win',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'android', 'gtk2', 'gtk3', 'qt', 'gonk', 'cocoa', 'uikit'}:
|
||||
DEFINES['SK_USE_POSIX_THREADS'] = 1
|
||||
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['HAVE_TOOLCHAIN_SUPPORT_MSSSE3']:
|
||||
DEFINES['SK_BUILD_SSSE3'] = 1
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
|
||||
DEFINES['SK_FONTHOST_CAIRO_STANDALONE'] = 0
|
||||
|
||||
@ -101,37 +74,33 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
|
||||
if CONFIG['_MSC_VER']:
|
||||
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
|
||||
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkBlitRect_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkMorphology_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkUtils_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkXfermode_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['/arch:AVX -DSK_CPU_SSE_LEVEL=51']
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['GNU_CC']:
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkBlitRect_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkMorphology_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkUtils_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkXfermode_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
|
||||
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['BUILD_ARM_NEON']:
|
||||
DEFINES['__ARM_HAVE_OPTIONAL_NEON_SUPPORT'] = 1
|
||||
DEFINES['USE_ANDROID_NDK_CPU_FEATURES'] = 0
|
||||
DEFINES['SK_ARM_HAS_OPTIONAL_NEON'] = 1
|
||||
elif CONFIG['CLANG_CL']:
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
|
||||
|
||||
DEFINES['SKIA_IMPLEMENTATION'] = 1
|
||||
DEFINES['GR_IMPLEMENTATION'] = 1
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += [
|
||||
@ -147,6 +116,8 @@ if CONFIG['GNU_CXX']:
|
||||
'-Wno-macro-redefined',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
# work around inline function linking bug with template arguments
|
||||
SOURCES['skia/src/gpu/GrResourceCache.cpp'].flags += ['-fkeep-inline-functions']
|
||||
else:
|
||||
CXXFLAGS += [
|
||||
'-Wno-logical-op',
|
||||
@ -180,7 +151,7 @@ def generate_platform_sources():
|
||||
sources = {}
|
||||
|
||||
for plat in platforms:
|
||||
if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s gyp/skia_lib.gyp" % plat) != 0:
|
||||
if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s -D host_os=linux gyp/skia_lib.gyp" % plat) != 0:
|
||||
print 'Failed to generate sources for ' + plat
|
||||
continue
|
||||
|
||||
@ -195,31 +166,26 @@ def generate_platform_sources():
|
||||
def generate_separated_sources(platform_sources):
|
||||
blacklist = [
|
||||
'ChromeUtils',
|
||||
'SkImageDecoder_',
|
||||
'_gif',
|
||||
'SkFontConfigParser_android',
|
||||
'SkJpeg',
|
||||
'SkXML',
|
||||
'SkCity',
|
||||
'GrGLCreateNativeInterface',
|
||||
'SkCreatePlatformGLContext',
|
||||
'fontconfig',
|
||||
'SkCondVar',
|
||||
'SkThreadUtils_pthread_',
|
||||
'SkImage_Codec',
|
||||
'SkBitmapChecksummer',
|
||||
'SkNativeGLContext',
|
||||
'SkFontConfig',
|
||||
'SkFontHost_win_dw',
|
||||
'SkFontMgr_android',
|
||||
'SkFontMgr_custom',
|
||||
'SkFontHost_FreeType.cpp',
|
||||
'SkForceLinking',
|
||||
'SkMovie',
|
||||
'SkImageDecoder',
|
||||
'SkImageEncoder',
|
||||
'SkBitmapHasher',
|
||||
'SkBitmapRegion',
|
||||
'codec',
|
||||
'SkWGL',
|
||||
'SkImages',
|
||||
'SkDiscardableMemory_ashmem',
|
||||
'SkMemory_malloc',
|
||||
'SkOpts_',
|
||||
'opts_check_x86',
|
||||
'third_party',
|
||||
]
|
||||
@ -233,30 +199,18 @@ def generate_separated_sources(platform_sources):
|
||||
|
||||
separated = defaultdict(set, {
|
||||
'common': {
|
||||
#'skia/src/effects/gradients/SkGradientTileProc.cpp',
|
||||
'skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
|
||||
'skia/src/ports/SkDiscardableMemory_none.cpp',
|
||||
'skia/src/ports/SkImageDecoder_empty.cpp',
|
||||
'skia/src/ports/SkMemory_mozalloc.cpp',
|
||||
# 'skia/src/images/SkImages.cpp',
|
||||
# 'skia/src/images/SkImageRef.cpp',
|
||||
# 'skia/src/images/SkImageRef_GlobalPool.cpp',
|
||||
# 'skia/src/images/SkImageRefPool.cpp',
|
||||
# 'skia/src/images/SkImageDecoder.cpp',
|
||||
# 'skia/src/images/SkImageDecoder_Factory.cpp',
|
||||
},
|
||||
'android': {
|
||||
# 'skia/src/ports/SkDebug_android.cpp',
|
||||
'skia/src/ports/SkFontHost_android_old.cpp',
|
||||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
# 'skia/src/ports/SkFontHost_FreeType.cpp',
|
||||
# 'skia/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
# 'skia/src/ports/SkThread_pthread.cpp',
|
||||
# 'skia/src/ports/SkPurgeableMemoryBlock_android.cpp',
|
||||
# 'skia/src/ports/SkTime_Unix.cpp',
|
||||
# 'skia/src/utils/SkThreadUtils_pthread.cpp',
|
||||
# 'skia/src/images/SkImageRef_ashmem.cpp',
|
||||
# 'skia/src/utils/android/ashmem.cpp',
|
||||
},
|
||||
'linux': {
|
||||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
@ -264,18 +218,18 @@ def generate_separated_sources(platform_sources):
|
||||
'intel': {
|
||||
# There is currently no x86-specific opt for SkTextureCompression
|
||||
'skia/src/opts/opts_check_x86.cpp',
|
||||
'skia/src/opts/SkTextureCompression_opts_none.cpp',
|
||||
'skia/src/opts/SkOpts_ssse3.cpp',
|
||||
'skia/src/opts/SkOpts_sse41.cpp',
|
||||
'skia/src/opts/SkOpts_avx.cpp',
|
||||
},
|
||||
'arm': {
|
||||
'skia/src/opts/SkUtils_opts_arm.cpp',
|
||||
'skia/src/core/SkUtilsArm.cpp',
|
||||
},
|
||||
'neon': {
|
||||
'skia/src/opts/SkOpts_neon.cpp',
|
||||
'skia/src/opts/SkBitmapProcState_arm_neon.cpp',
|
||||
},
|
||||
'none': {
|
||||
'skia/src/opts/SkUtils_opts_none.cpp',
|
||||
}
|
||||
'none': set()
|
||||
})
|
||||
|
||||
for plat in platform_sources.keys():
|
||||
@ -341,15 +295,22 @@ def write_sources(f, values, indent):
|
||||
'SkBlitter_Sprite.cpp',
|
||||
'SkBlitRow_opts_arm.cpp',
|
||||
'SkScan_Antihair.cpp',
|
||||
'SkCondVar.cpp',
|
||||
'SkParse.cpp',
|
||||
'GrAddPathRenderers_default.cpp',
|
||||
'GrDistanceFieldTextContext.cpp',
|
||||
'SkSHA1.cpp',
|
||||
'SkMD5.cpp',
|
||||
'SkPictureData.cpp',
|
||||
'SkScaledImageCache.cpp',
|
||||
'opts_check_x86.cpp',
|
||||
'GrDrawContext',
|
||||
'GrResourceCache',
|
||||
'GrAA',
|
||||
'GrGL',
|
||||
'GrBatchAtlas.cpp',
|
||||
'SkArithmeticMode_gpu.cpp',
|
||||
'SkImage_Gpu.cpp',
|
||||
'SkPathOpsDebug.cpp',
|
||||
'SkParsePath.cpp',
|
||||
'SkOpts',
|
||||
'SkRecorder.cpp',
|
||||
]
|
||||
|
||||
def isblacklisted(value):
|
||||
|
@ -14,26 +14,31 @@
|
||||
# DO NOT MODIFY THIS FILE IT IS AUTOGENERATED.
|
||||
#
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/c/sk_paint.cpp',
|
||||
'skia/src/c/sk_surface.cpp',
|
||||
'skia/src/core/SkAAClip.cpp',
|
||||
'skia/src/core/SkAlphaRuns.cpp',
|
||||
'skia/src/core/SkAnnotation.cpp',
|
||||
'skia/src/core/SkBBHFactory.cpp',
|
||||
'skia/src/core/SkBBoxHierarchyRecord.cpp',
|
||||
'skia/src/core/SkBBoxRecord.cpp',
|
||||
'skia/src/core/SkBigPicture.cpp',
|
||||
'skia/src/core/SkBitmap.cpp',
|
||||
'skia/src/core/SkBitmap_scroll.cpp',
|
||||
'skia/src/core/SkBitmapCache.cpp',
|
||||
'skia/src/core/SkBitmapController.cpp',
|
||||
'skia/src/core/SkBitmapDevice.cpp',
|
||||
'skia/src/core/SkBitmapFilter.cpp',
|
||||
'skia/src/core/SkBitmapHeap.cpp',
|
||||
'skia/src/core/SkBitmapProcShader.cpp',
|
||||
'skia/src/core/SkBitmapProcState.cpp',
|
||||
'skia/src/core/SkBitmapProvider.cpp',
|
||||
'skia/src/core/SkBitmapScaler.cpp',
|
||||
'skia/src/core/SkBlitMask_D32.cpp',
|
||||
'skia/src/core/SkBlitRow_D16.cpp',
|
||||
'skia/src/core/SkBlitRow_D32.cpp',
|
||||
'skia/src/core/SkBlitter.cpp',
|
||||
'skia/src/core/SkBuffer.cpp',
|
||||
'skia/src/core/SkCachedData.cpp',
|
||||
'skia/src/core/SkCanvas.cpp',
|
||||
'skia/src/core/SkChecksum.cpp',
|
||||
'skia/src/core/SkChunkAlloc.cpp',
|
||||
'skia/src/core/SkClipStack.cpp',
|
||||
'skia/src/core/SkColor.cpp',
|
||||
@ -53,6 +58,7 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/core/SkDistanceFieldGen.cpp',
|
||||
'skia/src/core/SkDither.cpp',
|
||||
'skia/src/core/SkDraw.cpp',
|
||||
'skia/src/core/SkDrawable.cpp',
|
||||
'skia/src/core/SkDrawLooper.cpp',
|
||||
'skia/src/core/SkEdge.cpp',
|
||||
'skia/src/core/SkEdgeBuilder.cpp',
|
||||
@ -62,75 +68,85 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/core/SkFilterShader.cpp',
|
||||
'skia/src/core/SkFlattenable.cpp',
|
||||
'skia/src/core/SkFlattenableSerialization.cpp',
|
||||
'skia/src/core/SkFloat.cpp',
|
||||
'skia/src/core/SkFloatBits.cpp',
|
||||
'skia/src/core/SkFont.cpp',
|
||||
'skia/src/core/SkFontDescriptor.cpp',
|
||||
'skia/src/core/SkFontMgr.cpp',
|
||||
'skia/src/core/SkFontStream.cpp',
|
||||
'skia/src/core/SkFontStyle.cpp',
|
||||
'skia/src/core/SkForceCPlusPlusLinking.cpp',
|
||||
'skia/src/core/SkGeometry.cpp',
|
||||
'skia/src/core/SkGlyphCache.cpp',
|
||||
'skia/src/core/SkGraphics.cpp',
|
||||
'skia/src/core/SkHalf.cpp',
|
||||
'skia/src/core/SkImageCacherator.cpp',
|
||||
'skia/src/core/SkImageFilter.cpp',
|
||||
'skia/src/core/SkImageGenerator.cpp',
|
||||
'skia/src/core/SkImageInfo.cpp',
|
||||
'skia/src/core/SkInstCnt.cpp',
|
||||
'skia/src/core/SkLightingShader.cpp',
|
||||
'skia/src/core/SkLineClipper.cpp',
|
||||
'skia/src/core/SkLocalMatrixImageFilter.cpp',
|
||||
'skia/src/core/SkLocalMatrixShader.cpp',
|
||||
'skia/src/core/SkMallocPixelRef.cpp',
|
||||
'skia/src/core/SkMask.cpp',
|
||||
'skia/src/core/SkMaskCache.cpp',
|
||||
'skia/src/core/SkMaskFilter.cpp',
|
||||
'skia/src/core/SkMaskGamma.cpp',
|
||||
'skia/src/core/SkMath.cpp',
|
||||
'skia/src/core/SkMatrix.cpp',
|
||||
'skia/src/core/SkMatrixClipStateMgr.cpp',
|
||||
'skia/src/core/SkMatrixImageFilter.cpp',
|
||||
'skia/src/core/SkMetaData.cpp',
|
||||
'skia/src/core/SkMiniRecorder.cpp',
|
||||
'skia/src/core/SkMipMap.cpp',
|
||||
'skia/src/core/SkMultiPictureDraw.cpp',
|
||||
'skia/src/core/SkNinePatchIter.cpp',
|
||||
'skia/src/core/SkPackBits.cpp',
|
||||
'skia/src/core/SkPaint.cpp',
|
||||
'skia/src/core/SkPaintOptionsAndroid.cpp',
|
||||
'skia/src/core/SkPaintPriv.cpp',
|
||||
'skia/src/core/SkPatch.cpp',
|
||||
'skia/src/core/SkPath.cpp',
|
||||
'skia/src/core/SkPathEffect.cpp',
|
||||
'skia/src/core/SkPathHeap.cpp',
|
||||
'skia/src/core/SkPathMeasure.cpp',
|
||||
'skia/src/core/SkPathRef.cpp',
|
||||
'skia/src/core/SkPicture.cpp',
|
||||
'skia/src/core/SkPictureContentInfo.cpp',
|
||||
'skia/src/core/SkPictureFlat.cpp',
|
||||
'skia/src/core/SkPictureImageGenerator.cpp',
|
||||
'skia/src/core/SkPicturePlayback.cpp',
|
||||
'skia/src/core/SkPictureRangePlayback.cpp',
|
||||
'skia/src/core/SkPictureRecord.cpp',
|
||||
'skia/src/core/SkPictureRecorder.cpp',
|
||||
'skia/src/core/SkPictureReplacementPlayback.cpp',
|
||||
'skia/src/core/SkPictureShader.cpp',
|
||||
'skia/src/core/SkPictureStateTree.cpp',
|
||||
'skia/src/core/SkPixelRef.cpp',
|
||||
'skia/src/core/SkPixmap.cpp',
|
||||
'skia/src/core/SkPoint.cpp',
|
||||
'skia/src/core/SkProcSpriteBlitter.cpp',
|
||||
'skia/src/core/SkPoint3.cpp',
|
||||
'skia/src/core/SkPtrRecorder.cpp',
|
||||
'skia/src/core/SkQuadClipper.cpp',
|
||||
'skia/src/core/SkQuadTree.cpp',
|
||||
'skia/src/core/SkRasterClip.cpp',
|
||||
'skia/src/core/SkRasterizer.cpp',
|
||||
'skia/src/core/SkReadBuffer.cpp',
|
||||
'skia/src/core/SkRecordAnalysis.cpp',
|
||||
'skia/src/core/SkRecord.cpp',
|
||||
'skia/src/core/SkRecordDraw.cpp',
|
||||
'skia/src/core/SkRecorder.cpp',
|
||||
'skia/src/core/SkRecording.cpp',
|
||||
'skia/src/core/SkRecordOpts.cpp',
|
||||
'skia/src/core/SkRecords.cpp',
|
||||
'skia/src/core/SkRect.cpp',
|
||||
'skia/src/core/SkRefDict.cpp',
|
||||
'skia/src/core/SkRegion.cpp',
|
||||
'skia/src/core/SkRegion_path.cpp',
|
||||
'skia/src/core/SkRemote.cpp',
|
||||
'skia/src/core/SkResourceCache.cpp',
|
||||
'skia/src/core/SkRRect.cpp',
|
||||
'skia/src/core/SkRTree.cpp',
|
||||
'skia/src/core/SkRWBuffer.cpp',
|
||||
'skia/src/core/SkScalar.cpp',
|
||||
'skia/src/core/SkScalerContext.cpp',
|
||||
'skia/src/core/SkScan.cpp',
|
||||
'skia/src/core/SkScan_AntiPath.cpp',
|
||||
'skia/src/core/SkScan_Hairline.cpp',
|
||||
'skia/src/core/SkScan_Path.cpp',
|
||||
'skia/src/core/SkSemaphore.cpp',
|
||||
'skia/src/core/SkShader.cpp',
|
||||
'skia/src/core/SkSharedMutex.cpp',
|
||||
'skia/src/core/SkSpinlock.cpp',
|
||||
'skia/src/core/SkSpriteBlitter_ARGB32.cpp',
|
||||
'skia/src/core/SkSpriteBlitter_RGB16.cpp',
|
||||
'skia/src/core/SkStream.cpp',
|
||||
@ -139,7 +155,10 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/core/SkStroke.cpp',
|
||||
'skia/src/core/SkStrokeRec.cpp',
|
||||
'skia/src/core/SkStrokerPriv.cpp',
|
||||
'skia/src/core/SkTileGrid.cpp',
|
||||
'skia/src/core/SkTaskGroup.cpp',
|
||||
'skia/src/core/SkTextBlob.cpp',
|
||||
'skia/src/core/SkThreadID.cpp',
|
||||
'skia/src/core/SkTime.cpp',
|
||||
'skia/src/core/SkTLS.cpp',
|
||||
'skia/src/core/SkTSearch.cpp',
|
||||
'skia/src/core/SkTypeface.cpp',
|
||||
@ -147,30 +166,33 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/core/SkUnPreMultiply.cpp',
|
||||
'skia/src/core/SkUtils.cpp',
|
||||
'skia/src/core/SkValidatingReadBuffer.cpp',
|
||||
'skia/src/core/SkVarAlloc.cpp',
|
||||
'skia/src/core/SkVertState.cpp',
|
||||
'skia/src/core/SkWriteBuffer.cpp',
|
||||
'skia/src/core/SkWriter32.cpp',
|
||||
'skia/src/core/SkXfermode.cpp',
|
||||
'skia/src/core/SkXfermodeInterpretation.cpp',
|
||||
'skia/src/core/SkYUVPlanesCache.cpp',
|
||||
'skia/src/doc/SkDocument.cpp',
|
||||
'skia/src/effects/gradients/SkBitmapCache.cpp',
|
||||
'skia/src/effects/gradients/SkClampRange.cpp',
|
||||
'skia/src/effects/gradients/SkGradientBitmapCache.cpp',
|
||||
'skia/src/effects/gradients/SkGradientShader.cpp',
|
||||
'skia/src/effects/gradients/SkLinearGradient.cpp',
|
||||
'skia/src/effects/gradients/SkRadialGradient.cpp',
|
||||
'skia/src/effects/gradients/SkSweepGradient.cpp',
|
||||
'skia/src/effects/gradients/SkTwoPointConicalGradient.cpp',
|
||||
'skia/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp',
|
||||
'skia/src/effects/gradients/SkTwoPointRadialGradient.cpp',
|
||||
'skia/src/effects/GrCircleBlurFragmentProcessor.cpp',
|
||||
'skia/src/effects/Sk1DPathEffect.cpp',
|
||||
'skia/src/effects/Sk2DPathEffect.cpp',
|
||||
'skia/src/effects/SkAlphaThresholdFilter.cpp',
|
||||
'skia/src/effects/SkArcToPathEffect.cpp',
|
||||
'skia/src/effects/SkArithmeticMode.cpp',
|
||||
'skia/src/effects/SkAvoidXfermode.cpp',
|
||||
'skia/src/effects/SkBitmapSource.cpp',
|
||||
'skia/src/effects/SkBlurDrawLooper.cpp',
|
||||
'skia/src/effects/SkBlurImageFilter.cpp',
|
||||
'skia/src/effects/SkBlurMask.cpp',
|
||||
'skia/src/effects/SkBlurMaskFilter.cpp',
|
||||
'skia/src/effects/SkColorCubeFilter.cpp',
|
||||
'skia/src/effects/SkColorFilterImageFilter.cpp',
|
||||
'skia/src/effects/SkColorFilters.cpp',
|
||||
'skia/src/effects/SkColorMatrix.cpp',
|
||||
@ -184,6 +206,7 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/effects/SkEmbossMask.cpp',
|
||||
'skia/src/effects/SkEmbossMaskFilter.cpp',
|
||||
'skia/src/effects/SkGpuBlurUtils.cpp',
|
||||
'skia/src/effects/SkImageSource.cpp',
|
||||
'skia/src/effects/SkLayerDrawLooper.cpp',
|
||||
'skia/src/effects/SkLayerRasterizer.cpp',
|
||||
'skia/src/effects/SkLerpXfermode.cpp',
|
||||
@ -191,7 +214,6 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/effects/SkLumaColorFilter.cpp',
|
||||
'skia/src/effects/SkMagnifierImageFilter.cpp',
|
||||
'skia/src/effects/SkMatrixConvolutionImageFilter.cpp',
|
||||
'skia/src/effects/SkMatrixImageFilter.cpp',
|
||||
'skia/src/effects/SkMergeImageFilter.cpp',
|
||||
'skia/src/effects/SkMorphologyImageFilter.cpp',
|
||||
'skia/src/effects/SkOffsetImageFilter.cpp',
|
||||
@ -199,131 +221,142 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/effects/SkPerlinNoiseShader.cpp',
|
||||
'skia/src/effects/SkPictureImageFilter.cpp',
|
||||
'skia/src/effects/SkPixelXorXfermode.cpp',
|
||||
'skia/src/effects/SkPorterDuff.cpp',
|
||||
'skia/src/effects/SkRectShaderImageFilter.cpp',
|
||||
'skia/src/effects/SkStippleMaskFilter.cpp',
|
||||
'skia/src/effects/SkTableColorFilter.cpp',
|
||||
'skia/src/effects/SkTableMaskFilter.cpp',
|
||||
'skia/src/effects/SkTestImageFilters.cpp',
|
||||
'skia/src/effects/SkTileImageFilter.cpp',
|
||||
'skia/src/effects/SkTransparentShader.cpp',
|
||||
'skia/src/effects/SkXfermodeImageFilter.cpp',
|
||||
'skia/src/fonts/SkFontMgr_indirect.cpp',
|
||||
'skia/src/fonts/SkGScalerContext.cpp',
|
||||
'skia/src/fonts/SkRandomScalerContext.cpp',
|
||||
'skia/src/fonts/SkRemotableFontMgr.cpp',
|
||||
'skia/src/fonts/SkTestScalerContext.cpp',
|
||||
'skia/src/gpu/batches/GrAtlasTextBatch.cpp',
|
||||
'skia/src/gpu/batches/GrBatch.cpp',
|
||||
'skia/src/gpu/batches/GrCopySurfaceBatch.cpp',
|
||||
'skia/src/gpu/batches/GrDashLinePathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrDefaultPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrDrawAtlasBatch.cpp',
|
||||
'skia/src/gpu/batches/GrDrawBatch.cpp',
|
||||
'skia/src/gpu/batches/GrDrawPathBatch.cpp',
|
||||
'skia/src/gpu/batches/GrDrawVerticesBatch.cpp',
|
||||
'skia/src/gpu/batches/GrNinePatch.cpp',
|
||||
'skia/src/gpu/batches/GrNonAAFillRectBatch.cpp',
|
||||
'skia/src/gpu/batches/GrNonAAStrokeRectBatch.cpp',
|
||||
'skia/src/gpu/batches/GrRectBatchFactory.cpp',
|
||||
'skia/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrTessellatingPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrVertexBatch.cpp',
|
||||
'skia/src/gpu/effects/GrBezierEffect.cpp',
|
||||
'skia/src/gpu/effects/GrBicubicEffect.cpp',
|
||||
'skia/src/gpu/effects/GrBitmapTextGeoProc.cpp',
|
||||
'skia/src/gpu/effects/GrConfigConversionEffect.cpp',
|
||||
'skia/src/gpu/effects/GrConstColorProcessor.cpp',
|
||||
'skia/src/gpu/effects/GrConvexPolyEffect.cpp',
|
||||
'skia/src/gpu/effects/GrConvolutionEffect.cpp',
|
||||
'skia/src/gpu/effects/GrCustomCoordsTextureEffect.cpp',
|
||||
'skia/src/gpu/effects/GrCoverageSetOpXP.cpp',
|
||||
'skia/src/gpu/effects/GrCustomXfermode.cpp',
|
||||
'skia/src/gpu/effects/GrDashingEffect.cpp',
|
||||
'skia/src/gpu/effects/GrDistanceFieldTextureEffect.cpp',
|
||||
'skia/src/gpu/effects/GrDisableColorXP.cpp',
|
||||
'skia/src/gpu/effects/GrDistanceFieldGeoProc.cpp',
|
||||
'skia/src/gpu/effects/GrDitherEffect.cpp',
|
||||
'skia/src/gpu/effects/GrMatrixConvolutionEffect.cpp',
|
||||
'skia/src/gpu/effects/GrOvalEffect.cpp',
|
||||
'skia/src/gpu/effects/GrPorterDuffXferProcessor.cpp',
|
||||
'skia/src/gpu/effects/GrRRectEffect.cpp',
|
||||
'skia/src/gpu/effects/GrSimpleTextureEffect.cpp',
|
||||
'skia/src/gpu/effects/GrSingleTextureEffect.cpp',
|
||||
'skia/src/gpu/effects/GrTextureDomain.cpp',
|
||||
'skia/src/gpu/effects/GrTextureStripAtlas.cpp',
|
||||
'skia/src/gpu/effects/GrXfermodeFragmentProcessor.cpp',
|
||||
'skia/src/gpu/effects/GrYUVtoRGBEffect.cpp',
|
||||
'skia/src/gpu/gl/debug/GrBufferObj.cpp',
|
||||
'skia/src/gpu/gl/debug/GrDebugGL.cpp',
|
||||
'skia/src/gpu/gl/debug/GrFrameBufferObj.cpp',
|
||||
'skia/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp',
|
||||
'skia/src/gpu/gl/debug/GrProgramObj.cpp',
|
||||
'skia/src/gpu/gl/debug/GrShaderObj.cpp',
|
||||
'skia/src/gpu/gl/debug/GrTextureObj.cpp',
|
||||
'skia/src/gpu/gl/debug/GrTextureUnitObj.cpp',
|
||||
'skia/src/gpu/gl/debug/SkDebugGLContext.cpp',
|
||||
'skia/src/gpu/gl/GrGLAssembleInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLBufferImpl.cpp',
|
||||
'skia/src/gpu/gl/GrGLCaps.cpp',
|
||||
'skia/src/gpu/gl/GrGLContext.cpp',
|
||||
'skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
|
||||
'skia/src/gpu/gl/GrGLCreateNullInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLDefaultInterface_native.cpp',
|
||||
'skia/src/gpu/gl/GrGLExtensions.cpp',
|
||||
'skia/src/gpu/gl/GrGLIndexBuffer.cpp',
|
||||
'skia/src/gpu/gl/GrGLInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLNameAllocator.cpp',
|
||||
'skia/src/gpu/gl/GrGLNoOpInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLPath.cpp',
|
||||
'skia/src/gpu/gl/GrGLPathRange.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgram.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgramDesc.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgramEffects.cpp',
|
||||
'skia/src/gpu/gl/GrGLRenderTarget.cpp',
|
||||
'skia/src/gpu/gl/GrGLShaderBuilder.cpp',
|
||||
'skia/src/gpu/gl/GrGLSL.cpp',
|
||||
'skia/src/gpu/gl/GrGLStencilBuffer.cpp',
|
||||
'skia/src/gpu/gl/GrGLTexture.cpp',
|
||||
'skia/src/gpu/gl/GrGLUniformManager.cpp',
|
||||
'skia/src/gpu/gl/GrGLUtil.cpp',
|
||||
'skia/src/gpu/gl/GrGLVertexArray.cpp',
|
||||
'skia/src/gpu/gl/GrGLVertexBuffer.cpp',
|
||||
'skia/src/gpu/gl/GrGpuGL.cpp',
|
||||
'skia/src/gpu/gl/GrGpuGL_program.cpp',
|
||||
'skia/src/gpu/gl/SkGLContextHelper.cpp',
|
||||
'skia/src/gpu/gl/SkGLContext.cpp',
|
||||
'skia/src/gpu/gl/SkNullGLContext.cpp',
|
||||
'skia/src/gpu/GrAAConvexPathRenderer.cpp',
|
||||
'skia/src/gpu/GrAAHairLinePathRenderer.cpp',
|
||||
'skia/src/gpu/GrAARectRenderer.cpp',
|
||||
'skia/src/gpu/GrAllocPool.cpp',
|
||||
'skia/src/gpu/GrAtlas.cpp',
|
||||
'skia/src/gpu/GrBitmapTextContext.cpp',
|
||||
'skia/src/gpu/GrAtlasTextBlob.cpp',
|
||||
'skia/src/gpu/GrAtlasTextContext.cpp',
|
||||
'skia/src/gpu/GrBatchFlushState.cpp',
|
||||
'skia/src/gpu/GrBatchFontCache.cpp',
|
||||
'skia/src/gpu/GrBatchTest.cpp',
|
||||
'skia/src/gpu/GrBlend.cpp',
|
||||
'skia/src/gpu/GrBlurUtils.cpp',
|
||||
'skia/src/gpu/GrBufferAllocPool.cpp',
|
||||
'skia/src/gpu/GrCacheID.cpp',
|
||||
'skia/src/gpu/GrClipData.cpp',
|
||||
'skia/src/gpu/GrClipMaskCache.cpp',
|
||||
'skia/src/gpu/GrCaps.cpp',
|
||||
'skia/src/gpu/GrClip.cpp',
|
||||
'skia/src/gpu/GrClipMaskManager.cpp',
|
||||
'skia/src/gpu/GrContext.cpp',
|
||||
'skia/src/gpu/GrDefaultPathRenderer.cpp',
|
||||
'skia/src/gpu/GrDrawState.cpp',
|
||||
'skia/src/gpu/GrCoordTransform.cpp',
|
||||
'skia/src/gpu/GrDefaultGeoProcFactory.cpp',
|
||||
'skia/src/gpu/GrDrawingManager.cpp',
|
||||
'skia/src/gpu/GrDrawTarget.cpp',
|
||||
'skia/src/gpu/GrEffect.cpp',
|
||||
'skia/src/gpu/GrFontScaler.cpp',
|
||||
'skia/src/gpu/GrFragmentProcessor.cpp',
|
||||
'skia/src/gpu/GrGpu.cpp',
|
||||
'skia/src/gpu/GrGpuFactory.cpp',
|
||||
'skia/src/gpu/GrGpuResource.cpp',
|
||||
'skia/src/gpu/GrInOrderDrawBuffer.cpp',
|
||||
'skia/src/gpu/GrGpuResourceRef.cpp',
|
||||
'skia/src/gpu/GrImageIDTextureAdjuster.cpp',
|
||||
'skia/src/gpu/GrInvariantOutput.cpp',
|
||||
'skia/src/gpu/GrLayerAtlas.cpp',
|
||||
'skia/src/gpu/GrLayerCache.cpp',
|
||||
'skia/src/gpu/GrLayerHoister.cpp',
|
||||
'skia/src/gpu/GrMemoryPool.cpp',
|
||||
'skia/src/gpu/GrOvalRenderer.cpp',
|
||||
'skia/src/gpu/GrPaint.cpp',
|
||||
'skia/src/gpu/GrPath.cpp',
|
||||
'skia/src/gpu/GrPathProcessor.cpp',
|
||||
'skia/src/gpu/GrPathRange.cpp',
|
||||
'skia/src/gpu/GrPathRenderer.cpp',
|
||||
'skia/src/gpu/GrPathRendererChain.cpp',
|
||||
'skia/src/gpu/GrPathRendering.cpp',
|
||||
'skia/src/gpu/GrPathUtils.cpp',
|
||||
'skia/src/gpu/GrPictureUtils.cpp',
|
||||
'skia/src/gpu/GrPipeline.cpp',
|
||||
'skia/src/gpu/GrPipelineBuilder.cpp',
|
||||
'skia/src/gpu/GrPrimitiveProcessor.cpp',
|
||||
'skia/src/gpu/GrProcessor.cpp',
|
||||
'skia/src/gpu/GrProcessorUnitTest.cpp',
|
||||
'skia/src/gpu/GrProcOptInfo.cpp',
|
||||
'skia/src/gpu/GrProgramElement.cpp',
|
||||
'skia/src/gpu/GrRecordReplaceDraw.cpp',
|
||||
'skia/src/gpu/GrRectanizer_pow2.cpp',
|
||||
'skia/src/gpu/GrRectanizer_skyline.cpp',
|
||||
'skia/src/gpu/GrReducedClip.cpp',
|
||||
'skia/src/gpu/GrRenderTarget.cpp',
|
||||
'skia/src/gpu/GrResourceCache.cpp',
|
||||
'skia/src/gpu/GrResourceProvider.cpp',
|
||||
'skia/src/gpu/GrSoftwarePathRenderer.cpp',
|
||||
'skia/src/gpu/GrStencil.cpp',
|
||||
'skia/src/gpu/GrStencilAndCoverPathRenderer.cpp',
|
||||
'skia/src/gpu/GrStencilAndCoverTextContext.cpp',
|
||||
'skia/src/gpu/GrStencilBuffer.cpp',
|
||||
'skia/src/gpu/GrStencilAttachment.cpp',
|
||||
'skia/src/gpu/GrStrokeInfo.cpp',
|
||||
'skia/src/gpu/GrSurface.cpp',
|
||||
'skia/src/gpu/GrSWMaskHelper.cpp',
|
||||
'skia/src/gpu/GrTestUtils.cpp',
|
||||
'skia/src/gpu/GrTextBlobCache.cpp',
|
||||
'skia/src/gpu/GrTextContext.cpp',
|
||||
'skia/src/gpu/GrTextStrike.cpp',
|
||||
'skia/src/gpu/GrTexture.cpp',
|
||||
'skia/src/gpu/GrTextureAccess.cpp',
|
||||
'skia/src/gpu/GrTextureParamsAdjuster.cpp',
|
||||
'skia/src/gpu/GrTextureProvider.cpp',
|
||||
'skia/src/gpu/GrTraceMarker.cpp',
|
||||
'skia/src/gpu/GrXferProcessor.cpp',
|
||||
'skia/src/gpu/GrYUVProvider.cpp',
|
||||
'skia/src/gpu/SkGpuDevice.cpp',
|
||||
'skia/src/gpu/SkGpuDevice_drawTexture.cpp',
|
||||
'skia/src/gpu/SkGr.cpp',
|
||||
'skia/src/gpu/SkGrPixelRef.cpp',
|
||||
'skia/src/gpu/SkGrTexturePixelRef.cpp',
|
||||
'skia/src/image/SkImage.cpp',
|
||||
'skia/src/image/SkImage_Gpu.cpp',
|
||||
'skia/src/image/SkImage_Generator.cpp',
|
||||
'skia/src/image/SkImage_Raster.cpp',
|
||||
'skia/src/image/SkImagePriv.cpp',
|
||||
'skia/src/image/SkImageShader.cpp',
|
||||
'skia/src/image/SkSurface.cpp',
|
||||
'skia/src/image/SkSurface_Gpu.cpp',
|
||||
'skia/src/image/SkSurface_Raster.cpp',
|
||||
@ -331,26 +364,27 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/images/SkDecodingImageGenerator.cpp',
|
||||
'skia/src/images/SkPageFlipper.cpp',
|
||||
'skia/src/images/SkScaledBitmapSampler.cpp',
|
||||
'skia/src/lazy/SkCachingPixelRef.cpp',
|
||||
'skia/src/lazy/SkDiscardableMemoryPool.cpp',
|
||||
'skia/src/lazy/SkDiscardablePixelRef.cpp',
|
||||
'skia/src/pathops/SkAddIntersections.cpp',
|
||||
'skia/src/pathops/SkDCubicIntersection.cpp',
|
||||
'skia/src/pathops/SkDConicLineIntersection.cpp',
|
||||
'skia/src/pathops/SkDCubicLineIntersection.cpp',
|
||||
'skia/src/pathops/SkDCubicToQuads.cpp',
|
||||
'skia/src/pathops/SkDLineIntersection.cpp',
|
||||
'skia/src/pathops/SkDQuadImplicit.cpp',
|
||||
'skia/src/pathops/SkDQuadIntersection.cpp',
|
||||
'skia/src/pathops/SkDQuadLineIntersection.cpp',
|
||||
'skia/src/pathops/SkIntersections.cpp',
|
||||
'skia/src/pathops/SkOpAngle.cpp',
|
||||
'skia/src/pathops/SkOpBuilder.cpp',
|
||||
'skia/src/pathops/SkOpCoincidence.cpp',
|
||||
'skia/src/pathops/SkOpContour.cpp',
|
||||
'skia/src/pathops/SkOpCubicHull.cpp',
|
||||
'skia/src/pathops/SkOpEdgeBuilder.cpp',
|
||||
'skia/src/pathops/SkOpSegment.cpp',
|
||||
'skia/src/pathops/SkPathOpsBounds.cpp',
|
||||
'skia/src/pathops/SkOpSpan.cpp',
|
||||
'skia/src/pathops/SkPathOpsCommon.cpp',
|
||||
'skia/src/pathops/SkPathOpsConic.cpp',
|
||||
'skia/src/pathops/SkPathOpsCubic.cpp',
|
||||
'skia/src/pathops/SkPathOpsDebug.cpp',
|
||||
'skia/src/pathops/SkPathOpsCurve.cpp',
|
||||
'skia/src/pathops/SkPathOpsLine.cpp',
|
||||
'skia/src/pathops/SkPathOpsOp.cpp',
|
||||
'skia/src/pathops/SkPathOpsPoint.cpp',
|
||||
@ -358,21 +392,24 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/pathops/SkPathOpsRect.cpp',
|
||||
'skia/src/pathops/SkPathOpsSimplify.cpp',
|
||||
'skia/src/pathops/SkPathOpsTightBounds.cpp',
|
||||
'skia/src/pathops/SkPathOpsTriangle.cpp',
|
||||
'skia/src/pathops/SkPathOpsTSect.cpp',
|
||||
'skia/src/pathops/SkPathOpsTypes.cpp',
|
||||
'skia/src/pathops/SkPathOpsWinding.cpp',
|
||||
'skia/src/pathops/SkPathWriter.cpp',
|
||||
'skia/src/pathops/SkQuarticRoot.cpp',
|
||||
'skia/src/pathops/SkReduceOrder.cpp',
|
||||
'skia/src/pipe/SkGPipeRead.cpp',
|
||||
'skia/src/pipe/SkGPipeWrite.cpp',
|
||||
'skia/src/ports/SkDiscardableMemory_none.cpp',
|
||||
'skia/src/ports/SkGlobalInitialization_default.cpp',
|
||||
'skia/src/ports/SkImageDecoder_empty.cpp',
|
||||
'skia/src/ports/SkImageGenerator_skia.cpp',
|
||||
'skia/src/ports/SkMemory_mozalloc.cpp',
|
||||
'skia/src/ports/SkOSFile_stdio.cpp',
|
||||
'skia/src/sfnt/SkOTTable_name.cpp',
|
||||
'skia/src/sfnt/SkOTUtils.cpp',
|
||||
'skia/src/utils/android/SkAndroidSDKCanvas.cpp',
|
||||
'skia/src/utils/SkBase64.cpp',
|
||||
'skia/src/utils/SkBitmapSourceDeserializer.cpp',
|
||||
'skia/src/utils/SkBitSet.cpp',
|
||||
'skia/src/utils/SkBoundaryPatch.cpp',
|
||||
'skia/src/utils/SkCamera.cpp',
|
||||
@ -381,11 +418,10 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/utils/SkCubicInterval.cpp',
|
||||
'skia/src/utils/SkCullPoints.cpp',
|
||||
'skia/src/utils/SkDashPath.cpp',
|
||||
'skia/src/utils/SkDeferredCanvas.cpp',
|
||||
'skia/src/utils/SkDumpCanvas.cpp',
|
||||
'skia/src/utils/SkEventTracer.cpp',
|
||||
'skia/src/utils/SkFrontBufferedStream.cpp',
|
||||
'skia/src/utils/SkGatherPixelRefsAndRects.cpp',
|
||||
'skia/src/utils/SkImageGeneratorUtils.cpp',
|
||||
'skia/src/utils/SkInterpolator.cpp',
|
||||
'skia/src/utils/SkLayer.cpp',
|
||||
'skia/src/utils/SkMatrix22.cpp',
|
||||
@ -395,16 +431,17 @@ UNIFIED_SOURCES += [
|
||||
'skia/src/utils/SkNullCanvas.cpp',
|
||||
'skia/src/utils/SkNWayCanvas.cpp',
|
||||
'skia/src/utils/SkOSFile.cpp',
|
||||
'skia/src/utils/SkPaintFilterCanvas.cpp',
|
||||
'skia/src/utils/SkParseColor.cpp',
|
||||
'skia/src/utils/SkParsePath.cpp',
|
||||
'skia/src/utils/SkPathUtils.cpp',
|
||||
'skia/src/utils/SkPictureUtils.cpp',
|
||||
'skia/src/utils/SkProxyCanvas.cpp',
|
||||
'skia/src/utils/SkPatchGrid.cpp',
|
||||
'skia/src/utils/SkPatchUtils.cpp',
|
||||
'skia/src/utils/SkRTConf.cpp',
|
||||
'skia/src/utils/SkTextBox.cpp',
|
||||
'skia/src/utils/SkTextureCompressor.cpp',
|
||||
'skia/src/utils/SkTextureCompressor_ASTC.cpp',
|
||||
'skia/src/utils/SkTextureCompressor_LATC.cpp',
|
||||
'skia/src/utils/SkTextureCompressor_R11EAC.cpp',
|
||||
'skia/src/utils/SkWhitelistTypefaces.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/core/SkAdvancedTypefaceMetrics.cpp',
|
||||
@ -414,33 +451,93 @@ SOURCES += [
|
||||
'skia/src/core/SkBlitter_RGB16.cpp',
|
||||
'skia/src/core/SkBlitter_Sprite.cpp',
|
||||
'skia/src/core/SkFontHost.cpp',
|
||||
'skia/src/core/SkOpts.cpp',
|
||||
'skia/src/core/SkPictureData.cpp',
|
||||
'skia/src/core/SkScaledImageCache.cpp',
|
||||
'skia/src/core/SkRecorder.cpp',
|
||||
'skia/src/core/SkScan_Antihair.cpp',
|
||||
'skia/src/gpu/GrAddPathRenderers_default.cpp',
|
||||
'skia/src/gpu/GrDistanceFieldTextContext.cpp',
|
||||
'skia/src/effects/SkArithmeticMode_gpu.cpp',
|
||||
'skia/src/gpu/batches/GrAAConvexPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrAAConvexTessellator.cpp',
|
||||
'skia/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrAAFillRectBatch.cpp',
|
||||
'skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp',
|
||||
'skia/src/gpu/batches/GrAAStrokeRectBatch.cpp',
|
||||
'skia/src/gpu/gl/builders/GrGLProgramBuilder.cpp',
|
||||
'skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp',
|
||||
'skia/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp',
|
||||
'skia/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLAssembleInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLBufferImpl.cpp',
|
||||
'skia/src/gpu/gl/GrGLCaps.cpp',
|
||||
'skia/src/gpu/gl/GrGLContext.cpp',
|
||||
'skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
|
||||
'skia/src/gpu/gl/GrGLCreateNullInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLDefaultInterface_native.cpp',
|
||||
'skia/src/gpu/gl/GrGLExtensions.cpp',
|
||||
'skia/src/gpu/gl/GrGLGLSL.cpp',
|
||||
'skia/src/gpu/gl/GrGLGpu.cpp',
|
||||
'skia/src/gpu/gl/GrGLGpuProgramCache.cpp',
|
||||
'skia/src/gpu/gl/GrGLIndexBuffer.cpp',
|
||||
'skia/src/gpu/gl/GrGLInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLNameAllocator.cpp',
|
||||
'skia/src/gpu/gl/GrGLNoOpInterface.cpp',
|
||||
'skia/src/gpu/gl/GrGLPath.cpp',
|
||||
'skia/src/gpu/gl/GrGLPathRange.cpp',
|
||||
'skia/src/gpu/gl/GrGLPathRendering.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgram.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgramDataManager.cpp',
|
||||
'skia/src/gpu/gl/GrGLProgramDesc.cpp',
|
||||
'skia/src/gpu/gl/GrGLRenderTarget.cpp',
|
||||
'skia/src/gpu/gl/GrGLStencilAttachment.cpp',
|
||||
'skia/src/gpu/gl/GrGLTexture.cpp',
|
||||
'skia/src/gpu/gl/GrGLTextureRenderTarget.cpp',
|
||||
'skia/src/gpu/gl/GrGLUtil.cpp',
|
||||
'skia/src/gpu/gl/GrGLVaryingHandler.cpp',
|
||||
'skia/src/gpu/gl/GrGLVertexArray.cpp',
|
||||
'skia/src/gpu/gl/GrGLVertexBuffer.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSL.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLBlend.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLCaps.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLFragmentProcessor.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLGeometryProcessor.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLProgramBuilder.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLShaderBuilder.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLUtil.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLVarying.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp',
|
||||
'skia/src/gpu/glsl/GrGLSLXferProcessor.cpp',
|
||||
'skia/src/gpu/GrBatchAtlas.cpp',
|
||||
'skia/src/gpu/GrDrawContext.cpp',
|
||||
'skia/src/gpu/GrResourceCache.cpp',
|
||||
'skia/src/image/SkImage_Gpu.cpp',
|
||||
'skia/src/pathops/SkPathOpsDebug.cpp',
|
||||
'skia/src/utils/SkMD5.cpp',
|
||||
'skia/src/utils/SkParse.cpp',
|
||||
'skia/src/utils/SkParsePath.cpp',
|
||||
'skia/src/utils/SkSHA1.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/ports/SkDebug_android.cpp',
|
||||
'skia/src/ports/SkOSFile_posix.cpp',
|
||||
'skia/src/ports/SkOSLibrary_posix.cpp',
|
||||
'skia/src/ports/SkTime_Unix.cpp',
|
||||
'skia/src/ports/SkTLS_pthread.cpp',
|
||||
'skia/src/utils/SkThreadUtils_pthread.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/ports/SkFontHost_android_old.cpp',
|
||||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/ports/SkDebug_stdio.cpp',
|
||||
'skia/src/ports/SkOSFile_posix.cpp',
|
||||
'skia/src/ports/SkOSLibrary_posix.cpp',
|
||||
'skia/src/ports/SkTime_Unix.cpp',
|
||||
'skia/src/ports/SkTLS_pthread.cpp',
|
||||
'skia/src/utils/mac/SkCreateCGImageRef.cpp',
|
||||
@ -454,35 +551,36 @@ if CONFIG['MOZ_WIDGET_GTK']:
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/ports/SkDebug_stdio.cpp',
|
||||
'skia/src/ports/SkOSFile_posix.cpp',
|
||||
'skia/src/ports/SkOSLibrary_posix.cpp',
|
||||
'skia/src/ports/SkTime_Unix.cpp',
|
||||
'skia/src/ports/SkTLS_pthread.cpp',
|
||||
'skia/src/utils/SkThreadUtils_pthread.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/ports/SkDebug_stdio.cpp',
|
||||
'skia/src/ports/SkOSFile_posix.cpp',
|
||||
'skia/src/ports/SkOSLibrary_posix.cpp',
|
||||
'skia/src/ports/SkTime_Unix.cpp',
|
||||
'skia/src/ports/SkTLS_pthread.cpp',
|
||||
'skia/src/utils/SkThreadUtils_pthread.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
SOURCES += [
|
||||
'skia/src/ports/SkDebug_win.cpp',
|
||||
'skia/src/ports/SkFontHost_win.cpp',
|
||||
'skia/src/ports/SkFontMgr_default_dw.cpp',
|
||||
'skia/src/ports/SkFontMgr_win_dw.cpp',
|
||||
'skia/src/ports/SkFontMgr_win_dw_factory.cpp',
|
||||
'skia/src/ports/SkOSFile_win.cpp',
|
||||
'skia/src/ports/SkOSLibrary_win.cpp',
|
||||
'skia/src/ports/SkRemotableFontMgr_win_dw.cpp',
|
||||
'skia/src/ports/SkScalerContext_win_dw.cpp',
|
||||
'skia/src/ports/SkTime_win.cpp',
|
||||
@ -497,32 +595,22 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'skia/src/utils/win/SkIStream.cpp',
|
||||
]
|
||||
if CONFIG['INTEL_ARCHITECTURE']:
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/opts/SkTextureCompression_opts_none.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/opts/opts_check_x86.cpp',
|
||||
'skia/src/opts/SkBitmapFilter_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBitmapProcState_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp',
|
||||
'skia/src/opts/SkBlitRect_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBlitRow_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBlurImage_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBlurImage_opts_SSE4.cpp',
|
||||
'skia/src/opts/SkMorphology_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkUtils_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkXfermode_opts_SSE2.cpp',
|
||||
'skia/src/opts/SkBlitRow_opts_SSE4.cpp',
|
||||
'skia/src/opts/SkOpts_avx.cpp',
|
||||
'skia/src/opts/SkOpts_sse41.cpp',
|
||||
'skia/src/opts/SkOpts_ssse3.cpp',
|
||||
]
|
||||
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/core/SkUtilsArm.cpp',
|
||||
'skia/src/opts/SkBitmapProcState_opts_arm.cpp',
|
||||
'skia/src/opts/SkBlitMask_opts_arm.cpp',
|
||||
'skia/src/opts/SkBlurImage_opts_arm.cpp',
|
||||
'skia/src/opts/SkMorphology_opts_arm.cpp',
|
||||
'skia/src/opts/SkTextureCompression_opts_arm.cpp',
|
||||
'skia/src/opts/SkUtils_opts_arm.cpp',
|
||||
'skia/src/opts/SkXfermode_opts_arm.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'skia/src/opts/SkBlitRow_opts_arm.cpp',
|
||||
@ -533,61 +621,27 @@ elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
|
||||
'skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp',
|
||||
'skia/src/opts/SkBlitMask_opts_arm_neon.cpp',
|
||||
'skia/src/opts/SkBlitRow_opts_arm_neon.cpp',
|
||||
'skia/src/opts/SkBlurImage_opts_neon.cpp',
|
||||
'skia/src/opts/SkMorphology_opts_neon.cpp',
|
||||
'skia/src/opts/SkTextureCompression_opts_neon.cpp',
|
||||
'skia/src/opts/SkXfermode_opts_arm_neon.cpp',
|
||||
'skia/src/opts/SkOpts_neon.cpp',
|
||||
]
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_arm_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkBlitMask_opts_arm_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_arm_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkMorphology_opts_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkTextureCompression_opts_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkXfermode_opts_arm_neon.cpp'].flags += ['-mfpu=neon']
|
||||
SOURCES['skia/src/opts/SkOpts_neon.cpp'].flags += ['-mfpu=neon']
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'skia/src/opts/SkBitmapProcState_opts_none.cpp',
|
||||
'skia/src/opts/SkBlitMask_opts_none.cpp',
|
||||
'skia/src/opts/SkBlitRow_opts_none.cpp',
|
||||
'skia/src/opts/SkBlurImage_opts_none.cpp',
|
||||
'skia/src/opts/SkMorphology_opts_none.cpp',
|
||||
'skia/src/opts/SkTextureCompression_opts_none.cpp',
|
||||
'skia/src/opts/SkUtils_opts_none.cpp',
|
||||
'skia/src/opts/SkXfermode_opts_none.cpp',
|
||||
]
|
||||
|
||||
|
||||
# can we find a better way of dealing with asm sources?
|
||||
|
||||
# left out of UNIFIED_SOURCES for now; that's not C++ anyway, nothing else to unify it with
|
||||
#XXX: doesn't build with Apple's assembler
|
||||
if not CONFIG['INTEL_ARCHITECTURE'] and CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['OS_TARGET'] != 'Darwin':
|
||||
SOURCES += [
|
||||
'skia/src/opts/memset.arm.S',
|
||||
]
|
||||
if CONFIG['BUILD_ARM_NEON']:
|
||||
SOURCES += [
|
||||
'skia/src/opts/memset16_neon.S',
|
||||
'skia/src/opts/memset32_neon.S',
|
||||
]
|
||||
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['GNU_CC'] and CONFIG['OS_ARCH'] != 'WINNT':
|
||||
if CONFIG['CPU_ARCH'] == 'x86_64':
|
||||
SOURCES += [
|
||||
'skia/src/opts/SkBlitRow_opts_SSE4_x64_asm.S',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'skia/src/opts/SkBlitRow_opts_SSE4_asm.S',
|
||||
]
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'gkmedias'
|
||||
LOCAL_INCLUDES += [
|
||||
'skia/include/c',
|
||||
'skia/include/config',
|
||||
'skia/include/core',
|
||||
'skia/include/effects',
|
||||
@ -596,6 +650,7 @@ LOCAL_INCLUDES += [
|
||||
'skia/include/pathops',
|
||||
'skia/include/pipe',
|
||||
'skia/include/ports',
|
||||
'skia/include/private',
|
||||
'skia/include/utils',
|
||||
'skia/include/utils/mac',
|
||||
'skia/include/utils/win',
|
||||
@ -613,16 +668,16 @@ LOCAL_INCLUDES += [
|
||||
'skia/src/utils/win',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'qt', 'gonk', 'cocoa', 'uikit'):
|
||||
DEFINES['SK_USE_POSIX_THREADS'] = 1
|
||||
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['HAVE_TOOLCHAIN_SUPPORT_MSSSE3']:
|
||||
DEFINES['SK_BUILD_SSSE3'] = 1
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
|
||||
DEFINES['SK_FONTHOST_CAIRO_STANDALONE'] = 0
|
||||
|
||||
if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'uikit') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk') or (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt') or CONFIG['MOZ_WIDGET_GTK']:
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
|
||||
'android',
|
||||
'cocoa',
|
||||
'uikit',
|
||||
'gonk',
|
||||
'qt',
|
||||
} or CONFIG['MOZ_WIDGET_GTK']:
|
||||
DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
|
||||
|
||||
# We should autogenerate these SSE related flags.
|
||||
@ -630,37 +685,33 @@ if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or (CONFIG['MOZ_WIDGET_TOOLKIT
|
||||
if CONFIG['_MSC_VER']:
|
||||
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
|
||||
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkBlitRect_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkMorphology_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkUtils_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkXfermode_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
|
||||
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=20']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=31']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['/arch:SSE2 -DSK_CPU_SSE_LEVEL=41']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['/arch:AVX -DSK_CPU_SSE_LEVEL=51']
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['GNU_CC']:
|
||||
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkBlitRect_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkMorphology_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkUtils_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkXfermode_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
|
||||
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['BUILD_ARM_NEON']:
|
||||
DEFINES['__ARM_HAVE_OPTIONAL_NEON_SUPPORT'] = 1
|
||||
DEFINES['USE_ANDROID_NDK_CPU_FEATURES'] = 0
|
||||
DEFINES['SK_ARM_HAS_OPTIONAL_NEON'] = 1
|
||||
elif CONFIG['CLANG_CL']:
|
||||
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkBlurImage_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkBlitRow_opts_SSE4.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-mssse3']
|
||||
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
|
||||
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
|
||||
|
||||
DEFINES['SKIA_IMPLEMENTATION'] = 1
|
||||
DEFINES['GR_IMPLEMENTATION'] = 1
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += [
|
||||
@ -676,6 +727,8 @@ if CONFIG['GNU_CXX']:
|
||||
'-Wno-macro-redefined',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
# work around inline function linking bug with template arguments
|
||||
SOURCES['skia/src/gpu/GrResourceCache.cpp'].flags += ['-fkeep-inline-functions']
|
||||
else:
|
||||
CXXFLAGS += [
|
||||
'-Wno-logical-op',
|
||||
|
29
gfx/skia/skia/include/android/SkBRDAllocator.h
Normal file
29
gfx/skia/skia/include/android/SkBRDAllocator.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBRDAllocator_DEFINED
|
||||
#define SkBRDAllocator_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCodec.h"
|
||||
|
||||
/**
|
||||
* Abstract subclass of SkBitmap's allocator.
|
||||
* Allows the allocator to indicate if the memory it allocates
|
||||
* is zero initialized.
|
||||
*/
|
||||
class SkBRDAllocator : public SkBitmap::Allocator {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Indicates if the memory allocated by this allocator is
|
||||
* zero initialized.
|
||||
*/
|
||||
virtual SkCodec::ZeroInitialized zeroInit() const = 0;
|
||||
};
|
||||
|
||||
#endif // SkBRDAllocator_DEFINED
|
90
gfx/skia/skia/include/android/SkBitmapRegionDecoder.h
Normal file
90
gfx/skia/skia/include/android/SkBitmapRegionDecoder.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBitmapRegionDecoder_DEFINED
|
||||
#define SkBitmapRegionDecoder_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkBRDAllocator.h"
|
||||
#include "SkEncodedFormat.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
/*
|
||||
* This class aims to provide an interface to test multiple implementations of
|
||||
* SkBitmapRegionDecoder.
|
||||
*/
|
||||
class SkBitmapRegionDecoder {
|
||||
public:
|
||||
|
||||
enum Strategy {
|
||||
kCanvas_Strategy, // Draw to the canvas, uses SkCodec
|
||||
kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting
|
||||
};
|
||||
|
||||
/*
|
||||
* @param data Refs the data while this object exists, unrefs on destruction
|
||||
* @param strategy Strategy used for scaling and subsetting
|
||||
* @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure
|
||||
*/
|
||||
static SkBitmapRegionDecoder* Create(
|
||||
SkData* data, Strategy strategy);
|
||||
|
||||
/*
|
||||
* @param stream Takes ownership of the stream
|
||||
* @param strategy Strategy used for scaling and subsetting
|
||||
* @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure
|
||||
*/
|
||||
static SkBitmapRegionDecoder* Create(
|
||||
SkStreamRewindable* stream, Strategy strategy);
|
||||
|
||||
/*
|
||||
* Decode a scaled region of the encoded image stream
|
||||
*
|
||||
* @param bitmap Container for decoded pixels. It is assumed that the pixels
|
||||
* are initially unallocated and will be allocated by this function.
|
||||
* @param allocator Allocator for the pixels. If this is NULL, the default
|
||||
* allocator (HeapAllocator) will be used.
|
||||
* @param desiredSubset Subset of the original image to decode.
|
||||
* @param sampleSize An integer downscaling factor for the decode.
|
||||
* @param colorType Preferred output colorType.
|
||||
* New implementations should return NULL if they do not support
|
||||
* decoding to this color type.
|
||||
* The old kOriginal_Strategy will decode to a default color type
|
||||
* if this color type is unsupported.
|
||||
* @param requireUnpremul If the image is not opaque, we will use this to determine the
|
||||
* alpha type to use.
|
||||
*
|
||||
*/
|
||||
virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
|
||||
const SkIRect& desiredSubset, int sampleSize,
|
||||
SkColorType colorType, bool requireUnpremul) = 0;
|
||||
/*
|
||||
* @param Requested destination color type
|
||||
* @return true if we support the requested color type and false otherwise
|
||||
*/
|
||||
virtual bool conversionSupported(SkColorType colorType) = 0;
|
||||
|
||||
virtual SkEncodedFormat getEncodedFormat() = 0;
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
|
||||
virtual ~SkBitmapRegionDecoder() {}
|
||||
|
||||
protected:
|
||||
|
||||
SkBitmapRegionDecoder(int width, int height)
|
||||
: fWidth(width)
|
||||
, fHeight(height)
|
||||
{}
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
};
|
||||
|
||||
#endif
|
154
gfx/skia/skia/include/c/sk_canvas.h
Normal file
154
gfx/skia/skia/include/c/sk_canvas.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_canvas_DEFINED
|
||||
#define sk_canvas_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Save the current matrix and clip on the canvas. When the
|
||||
balancing call to sk_canvas_restore() is made, the previous matrix
|
||||
and clip are restored.
|
||||
*/
|
||||
SK_API void sk_canvas_save(sk_canvas_t*);
|
||||
/**
|
||||
This behaves the same as sk_canvas_save(), but in addition it
|
||||
allocates an offscreen surface. All drawing calls are directed
|
||||
there, and only when the balancing call to sk_canvas_restore() is
|
||||
made is that offscreen transfered to the canvas (or the previous
|
||||
layer).
|
||||
|
||||
@param sk_rect_t* (may be null) This rect, if non-null, is used as
|
||||
a hint to limit the size of the offscreen, and
|
||||
thus drawing may be clipped to it, though that
|
||||
clipping is not guaranteed to happen. If exact
|
||||
clipping is desired, use sk_canvas_clip_rect().
|
||||
@param sk_paint_t* (may be null) The paint is copied, and is applied
|
||||
to the offscreen when sk_canvas_restore() is
|
||||
called.
|
||||
*/
|
||||
SK_API void sk_canvas_save_layer(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
|
||||
/**
|
||||
This call balances a previous call to sk_canvas_save() or
|
||||
sk_canvas_save_layer(), and is used to remove all modifications to
|
||||
the matrix and clip state since the last save call. It is an
|
||||
error to call sk_canvas_restore() more times than save and
|
||||
save_layer were called.
|
||||
*/
|
||||
SK_API void sk_canvas_restore(sk_canvas_t*);
|
||||
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified translation.
|
||||
*/
|
||||
SK_API void sk_canvas_translate(sk_canvas_t*, float dx, float dy);
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified scale.
|
||||
*/
|
||||
SK_API void sk_canvas_scale(sk_canvas_t*, float sx, float sy);
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified rotation in degrees.
|
||||
*/
|
||||
SK_API void sk_canvas_rotate_degrees(sk_canvas_t*, float degrees);
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified rotation in radians.
|
||||
*/
|
||||
SK_API void sk_canvas_rotate_radians(sk_canvas_t*, float radians);
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified skew.
|
||||
*/
|
||||
SK_API void sk_canvas_skew(sk_canvas_t*, float sx, float sy);
|
||||
/**
|
||||
Preconcat the current coordinate transformation matrix with the
|
||||
specified matrix.
|
||||
*/
|
||||
SK_API void sk_canvas_concat(sk_canvas_t*, const sk_matrix_t*);
|
||||
|
||||
/**
|
||||
Modify the current clip with the specified rectangle. The new
|
||||
current clip will be the intersection of the old clip and the
|
||||
rectange.
|
||||
*/
|
||||
SK_API void sk_canvas_clip_rect(sk_canvas_t*, const sk_rect_t*);
|
||||
/**
|
||||
Modify the current clip with the specified path. The new
|
||||
current clip will be the intersection of the old clip and the
|
||||
path.
|
||||
*/
|
||||
SK_API void sk_canvas_clip_path(sk_canvas_t*, const sk_path_t*);
|
||||
|
||||
/**
|
||||
Fill the entire canvas (restricted to the current clip) with the
|
||||
specified paint.
|
||||
*/
|
||||
SK_API void sk_canvas_draw_paint(sk_canvas_t*, const sk_paint_t*);
|
||||
/**
|
||||
Draw the specified rectangle using the specified paint. The
|
||||
rectangle will be filled or stroked based on the style in the
|
||||
paint.
|
||||
*/
|
||||
SK_API void sk_canvas_draw_rect(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
|
||||
/**
|
||||
Draw the specified oval using the specified paint. The oval will be
|
||||
filled or framed based on the style in the paint
|
||||
*/
|
||||
SK_API void sk_canvas_draw_oval(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
|
||||
/**
|
||||
Draw the specified path using the specified paint. The path will be
|
||||
filled or framed based on the style in the paint
|
||||
*/
|
||||
SK_API void sk_canvas_draw_path(sk_canvas_t*, const sk_path_t*, const sk_paint_t*);
|
||||
/**
|
||||
Draw the specified image, with its top/left corner at (x,y), using
|
||||
the specified paint, transformed by the current matrix.
|
||||
|
||||
@param sk_paint_t* (may be NULL) the paint used to draw the image.
|
||||
*/
|
||||
SK_API void sk_canvas_draw_image(sk_canvas_t*, const sk_image_t*,
|
||||
float x, float y, const sk_paint_t*);
|
||||
/**
|
||||
Draw the specified image, scaling and translating so that it fills
|
||||
the specified dst rect. If the src rect is non-null, only that
|
||||
subset of the image is transformed and drawn.
|
||||
|
||||
@param sk_paint_t* (may be NULL) The paint used to draw the image.
|
||||
*/
|
||||
SK_API void sk_canvas_draw_image_rect(sk_canvas_t*, const sk_image_t*,
|
||||
const sk_rect_t* src,
|
||||
const sk_rect_t* dst, const sk_paint_t*);
|
||||
|
||||
/**
|
||||
Draw the picture into this canvas (replay the pciture's drawing commands).
|
||||
|
||||
@param sk_matrix_t* If non-null, apply that matrix to the CTM when
|
||||
drawing this picture. This is logically
|
||||
equivalent to: save, concat, draw_picture,
|
||||
restore.
|
||||
|
||||
@param sk_paint_t* If non-null, draw the picture into a temporary
|
||||
buffer, and then apply the paint's alpha,
|
||||
colorfilter, imagefilter, and xfermode to that
|
||||
buffer as it is drawn to the canvas. This is
|
||||
logically equivalent to save_layer(paint),
|
||||
draw_picture, restore.
|
||||
*/
|
||||
SK_API void sk_canvas_draw_picture(sk_canvas_t*, const sk_picture_t*,
|
||||
const sk_matrix_t*, const sk_paint_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
70
gfx/skia/skia/include/c/sk_data.h
Normal file
70
gfx/skia/skia/include/c/sk_data.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_data_DEFINED
|
||||
#define sk_data_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Returns a new empty sk_data_t. This call must be balanced with a call to
|
||||
sk_data_unref().
|
||||
*/
|
||||
SK_API sk_data_t* sk_data_new_empty();
|
||||
/**
|
||||
Returns a new sk_data_t by copying the specified source data.
|
||||
This call must be balanced with a call to sk_data_unref().
|
||||
*/
|
||||
SK_API sk_data_t* sk_data_new_with_copy(const void* src, size_t length);
|
||||
/**
|
||||
Pass ownership of the given memory to a new sk_data_t, which will
|
||||
call free() when the refernce count of the data goes to zero. For
|
||||
example:
|
||||
size_t length = 1024;
|
||||
void* buffer = malloc(length);
|
||||
memset(buffer, 'X', length);
|
||||
sk_data_t* data = sk_data_new_from_malloc(buffer, length);
|
||||
This call must be balanced with a call to sk_data_unref().
|
||||
*/
|
||||
SK_API sk_data_t* sk_data_new_from_malloc(const void* memory, size_t length);
|
||||
/**
|
||||
Returns a new sk_data_t using a subset of the data in the
|
||||
specified source sk_data_t. This call must be balanced with a
|
||||
call to sk_data_unref().
|
||||
*/
|
||||
SK_API sk_data_t* sk_data_new_subset(const sk_data_t* src, size_t offset, size_t length);
|
||||
|
||||
/**
|
||||
Increment the reference count on the given sk_data_t. Must be
|
||||
balanced by a call to sk_data_unref().
|
||||
*/
|
||||
SK_API void sk_data_ref(const sk_data_t*);
|
||||
/**
|
||||
Decrement the reference count. If the reference count is 1 before
|
||||
the decrement, then release both the memory holding the sk_data_t
|
||||
and the memory it is managing. New sk_data_t are created with a
|
||||
reference count of 1.
|
||||
*/
|
||||
SK_API void sk_data_unref(const sk_data_t*);
|
||||
|
||||
/**
|
||||
Returns the number of bytes stored.
|
||||
*/
|
||||
SK_API size_t sk_data_get_size(const sk_data_t*);
|
||||
/**
|
||||
Returns the pointer to the data.
|
||||
*/
|
||||
SK_API const void* sk_data_get_data(const sk_data_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
71
gfx/skia/skia/include/c/sk_image.h
Normal file
71
gfx/skia/skia/include/c/sk_image.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_image_DEFINED
|
||||
#define sk_image_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
* Return a new image that has made a copy of the provided pixels, or NULL on failure.
|
||||
* Balance with a call to sk_image_unref().
|
||||
*/
|
||||
SK_API sk_image_t* sk_image_new_raster_copy(const sk_imageinfo_t*, const void* pixels, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* If the specified data can be interpreted as a compressed image (e.g. PNG or JPEG) then this
|
||||
* returns an image. If the encoded data is not supported, returns NULL.
|
||||
*
|
||||
* On success, the encoded data may be processed immediately, or it may be ref()'d for later
|
||||
* use.
|
||||
*/
|
||||
SK_API sk_image_t* sk_image_new_from_encoded(const sk_data_t* encoded, const sk_irect_t* subset);
|
||||
|
||||
/**
|
||||
* Encode the image's pixels and return the result as a new PNG in a
|
||||
* sk_data_t, which the caller must manage: call sk_data_unref() when
|
||||
* they are done.
|
||||
*
|
||||
* If the image type cannot be encoded, this will return NULL.
|
||||
*/
|
||||
SK_API sk_data_t* sk_image_encode(const sk_image_t*);
|
||||
|
||||
/**
|
||||
* Increment the reference count on the given sk_image_t. Must be
|
||||
* balanced by a call to sk_image_unref().
|
||||
*/
|
||||
SK_API void sk_image_ref(const sk_image_t*);
|
||||
/**
|
||||
* Decrement the reference count. If the reference count is 1 before
|
||||
* the decrement, then release both the memory holding the sk_image_t
|
||||
* and the memory it is managing. New sk_image_t are created with a
|
||||
reference count of 1.
|
||||
*/
|
||||
SK_API void sk_image_unref(const sk_image_t*);
|
||||
|
||||
/**
|
||||
* Return the width of the sk_image_t/
|
||||
*/
|
||||
SK_API int sk_image_get_width(const sk_image_t*);
|
||||
/**
|
||||
* Return the height of the sk_image_t/
|
||||
*/
|
||||
SK_API int sk_image_get_height(const sk_image_t*);
|
||||
|
||||
/**
|
||||
* Returns a non-zero value unique among all images.
|
||||
*/
|
||||
SK_API uint32_t sk_image_get_unique_id(const sk_image_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
47
gfx/skia/skia/include/c/sk_maskfilter.h
Normal file
47
gfx/skia/skia/include/c/sk_maskfilter.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_maskfilter_DEFINED
|
||||
#define sk_maskfilter_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
typedef enum {
|
||||
NORMAL_SK_BLUR_STYLE, //!< fuzzy inside and outside
|
||||
SOLID_SK_BLUR_STYLE, //!< solid inside, fuzzy outside
|
||||
OUTER_SK_BLUR_STYLE, //!< nothing inside, fuzzy outside
|
||||
INNER_SK_BLUR_STYLE, //!< fuzzy inside, nothing outside
|
||||
} sk_blurstyle_t;
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Increment the reference count on the given sk_maskfilter_t. Must be
|
||||
balanced by a call to sk_maskfilter_unref().
|
||||
*/
|
||||
void sk_maskfilter_ref(sk_maskfilter_t*);
|
||||
/**
|
||||
Decrement the reference count. If the reference count is 1 before
|
||||
the decrement, then release both the memory holding the
|
||||
sk_maskfilter_t and any other associated resources. New
|
||||
sk_maskfilter_t are created with a reference count of 1.
|
||||
*/
|
||||
void sk_maskfilter_unref(sk_maskfilter_t*);
|
||||
|
||||
/**
|
||||
Create a blur maskfilter.
|
||||
@param sk_blurstyle_t The SkBlurStyle to use
|
||||
@param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
|
||||
*/
|
||||
sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t, float sigma);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
49
gfx/skia/skia/include/c/sk_matrix.h
Normal file
49
gfx/skia/skia/include/c/sk_matrix.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_matrix_DEFINED
|
||||
#define sk_matrix_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/** Set the matrix to identity */
|
||||
void sk_matrix_set_identity(sk_matrix_t*);
|
||||
|
||||
/** Set the matrix to translate by (tx, ty). */
|
||||
void sk_matrix_set_translate(sk_matrix_t*, float tx, float ty);
|
||||
/**
|
||||
Preconcats the matrix with the specified translation.
|
||||
M' = M * T(dx, dy)
|
||||
*/
|
||||
void sk_matrix_pre_translate(sk_matrix_t*, float tx, float ty);
|
||||
/**
|
||||
Postconcats the matrix with the specified translation.
|
||||
M' = T(dx, dy) * M
|
||||
*/
|
||||
void sk_matrix_post_translate(sk_matrix_t*, float tx, float ty);
|
||||
|
||||
/** Set the matrix to scale by sx and sy. */
|
||||
void sk_matrix_set_scale(sk_matrix_t*, float sx, float sy);
|
||||
/**
|
||||
Preconcats the matrix with the specified scale.
|
||||
M' = M * S(sx, sy)
|
||||
*/
|
||||
void sk_matrix_pre_scale(sk_matrix_t*, float sx, float sy);
|
||||
/**
|
||||
Postconcats the matrix with the specified scale.
|
||||
M' = S(sx, sy) * M
|
||||
*/
|
||||
void sk_matrix_post_scale(sk_matrix_t*, float sx, float sy);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
145
gfx/skia/skia/include/c/sk_paint.h
Normal file
145
gfx/skia/skia/include/c/sk_paint.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_paint_DEFINED
|
||||
#define sk_paint_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Create a new paint with default settings:
|
||||
antialias : false
|
||||
stroke : false
|
||||
stroke width : 0.0f (hairline)
|
||||
stroke miter : 4.0f
|
||||
stroke cap : BUTT_SK_STROKE_CAP
|
||||
stroke join : MITER_SK_STROKE_JOIN
|
||||
color : opaque black
|
||||
shader : NULL
|
||||
maskfilter : NULL
|
||||
xfermode_mode : SRCOVER_SK_XFERMODE_MODE
|
||||
*/
|
||||
SK_API sk_paint_t* sk_paint_new();
|
||||
/**
|
||||
Release the memory storing the sk_paint_t and unref() all
|
||||
associated objects.
|
||||
*/
|
||||
SK_API void sk_paint_delete(sk_paint_t*);
|
||||
|
||||
/**
|
||||
Return true iff the paint has antialiasing enabled.
|
||||
*/
|
||||
SK_API bool sk_paint_is_antialias(const sk_paint_t*);
|
||||
/**
|
||||
Set to true to enable antialiasing, false to disable it on this
|
||||
sk_paint_t.
|
||||
*/
|
||||
SK_API void sk_paint_set_antialias(sk_paint_t*, bool);
|
||||
|
||||
/**
|
||||
Return the paint's curent drawing color.
|
||||
*/
|
||||
SK_API sk_color_t sk_paint_get_color(const sk_paint_t*);
|
||||
/**
|
||||
Set the paint's curent drawing color.
|
||||
*/
|
||||
SK_API void sk_paint_set_color(sk_paint_t*, sk_color_t);
|
||||
|
||||
/* stroke settings */
|
||||
|
||||
/**
|
||||
Return true iff stroking is enabled rather than filling on this
|
||||
sk_paint_t.
|
||||
*/
|
||||
SK_API bool sk_paint_is_stroke(const sk_paint_t*);
|
||||
/**
|
||||
Set to true to enable stroking rather than filling with this
|
||||
sk_paint_t.
|
||||
*/
|
||||
SK_API void sk_paint_set_stroke(sk_paint_t*, bool);
|
||||
|
||||
/**
|
||||
Return the width for stroking. A value of 0 strokes in hairline mode.
|
||||
*/
|
||||
SK_API float sk_paint_get_stroke_width(const sk_paint_t*);
|
||||
/**
|
||||
Set the width for stroking. A value of 0 strokes in hairline mode
|
||||
(always draw 1-pixel wide, regardless of the matrix).
|
||||
*/
|
||||
SK_API void sk_paint_set_stroke_width(sk_paint_t*, float width);
|
||||
|
||||
/**
|
||||
Return the paint's stroke miter value. This is used to control the
|
||||
behavior of miter joins when the joins angle is sharp.
|
||||
*/
|
||||
SK_API float sk_paint_get_stroke_miter(const sk_paint_t*);
|
||||
/**
|
||||
Set the paint's stroke miter value. This is used to control the
|
||||
behavior of miter joins when the joins angle is sharp. This value
|
||||
must be >= 0.
|
||||
*/
|
||||
SK_API void sk_paint_set_stroke_miter(sk_paint_t*, float miter);
|
||||
|
||||
typedef enum {
|
||||
BUTT_SK_STROKE_CAP,
|
||||
ROUND_SK_STROKE_CAP,
|
||||
SQUARE_SK_STROKE_CAP
|
||||
} sk_stroke_cap_t;
|
||||
|
||||
/**
|
||||
Return the paint's stroke cap type, controlling how the start and
|
||||
end of stroked lines and paths are treated.
|
||||
*/
|
||||
SK_API sk_stroke_cap_t sk_paint_get_stroke_cap(const sk_paint_t*);
|
||||
/**
|
||||
Set the paint's stroke cap type, controlling how the start and
|
||||
end of stroked lines and paths are treated.
|
||||
*/
|
||||
SK_API void sk_paint_set_stroke_cap(sk_paint_t*, sk_stroke_cap_t);
|
||||
|
||||
typedef enum {
|
||||
MITER_SK_STROKE_JOIN,
|
||||
ROUND_SK_STROKE_JOIN,
|
||||
BEVEL_SK_STROKE_JOIN
|
||||
} sk_stroke_join_t;
|
||||
|
||||
/**
|
||||
Return the paint's stroke join type, specifies the treatment that
|
||||
is applied to corners in paths and rectangles
|
||||
*/
|
||||
SK_API sk_stroke_join_t sk_paint_get_stroke_join(const sk_paint_t*);
|
||||
/**
|
||||
Set the paint's stroke join type, specifies the treatment that
|
||||
is applied to corners in paths and rectangles
|
||||
*/
|
||||
SK_API void sk_paint_set_stroke_join(sk_paint_t*, sk_stroke_join_t);
|
||||
|
||||
/**
|
||||
* Set the paint's shader to the specified parameter. This will automatically call unref() on
|
||||
* any previous value, and call ref() on the new value.
|
||||
*/
|
||||
SK_API void sk_paint_set_shader(sk_paint_t*, sk_shader_t*);
|
||||
|
||||
/**
|
||||
* Set the paint's maskfilter to the specified parameter. This will automatically call unref() on
|
||||
* any previous value, and call ref() on the new value.
|
||||
*/
|
||||
SK_API void sk_paint_set_maskfilter(sk_paint_t*, sk_maskfilter_t*);
|
||||
|
||||
/**
|
||||
* Set the paint's xfermode to the specified parameter.
|
||||
*/
|
||||
SK_API void sk_paint_set_xfermode_mode(sk_paint_t*, sk_xfermode_mode_t);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
84
gfx/skia/skia/include/c/sk_path.h
Normal file
84
gfx/skia/skia/include/c/sk_path.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_path_DEFINED
|
||||
#define sk_path_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
typedef enum {
|
||||
CW_SK_PATH_DIRECTION,
|
||||
CCW_SK_PATH_DIRECTION,
|
||||
} sk_path_direction_t;
|
||||
|
||||
/** Create a new, empty path. */
|
||||
SK_API sk_path_t* sk_path_new();
|
||||
/** Release the memory used by a sk_path_t. */
|
||||
SK_API void sk_path_delete(sk_path_t*);
|
||||
|
||||
/** Set the beginning of the next contour to the point (x,y). */
|
||||
SK_API void sk_path_move_to(sk_path_t*, float x, float y);
|
||||
/**
|
||||
Add a line from the last point to the specified point (x,y). If no
|
||||
sk_path_move_to() call has been made for this contour, the first
|
||||
point is automatically set to (0,0).
|
||||
*/
|
||||
SK_API void sk_path_line_to(sk_path_t*, float x, float y);
|
||||
/**
|
||||
Add a quadratic bezier from the last point, approaching control
|
||||
point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call
|
||||
has been made for this contour, the first point is automatically
|
||||
set to (0,0).
|
||||
*/
|
||||
SK_API void sk_path_quad_to(sk_path_t*, float x0, float y0, float x1, float y1);
|
||||
/**
|
||||
Add a conic curve from the last point, approaching control point
|
||||
(x0,y01), and ending at (x1,y1) with weight w. If no
|
||||
sk_path_move_to() call has been made for this contour, the first
|
||||
point is automatically set to (0,0).
|
||||
*/
|
||||
SK_API void sk_path_conic_to(sk_path_t*, float x0, float y0, float x1, float y1, float w);
|
||||
/**
|
||||
Add a cubic bezier from the last point, approaching control points
|
||||
(x0,y0) and (x1,y1), and ending at (x2,y2). If no
|
||||
sk_path_move_to() call has been made for this contour, the first
|
||||
point is automatically set to (0,0).
|
||||
*/
|
||||
SK_API void sk_path_cubic_to(sk_path_t*,
|
||||
float x0, float y0,
|
||||
float x1, float y1,
|
||||
float x2, float y2);
|
||||
/**
|
||||
Close the current contour. If the current point is not equal to the
|
||||
first point of the contour, a line segment is automatically added.
|
||||
*/
|
||||
SK_API void sk_path_close(sk_path_t*);
|
||||
|
||||
/**
|
||||
Add a closed rectangle contour to the path.
|
||||
*/
|
||||
SK_API void sk_path_add_rect(sk_path_t*, const sk_rect_t*, sk_path_direction_t);
|
||||
/**
|
||||
Add a closed oval contour to the path
|
||||
*/
|
||||
SK_API void sk_path_add_oval(sk_path_t*, const sk_rect_t*, sk_path_direction_t);
|
||||
|
||||
/**
|
||||
* If the path is empty, return false and set the rect parameter to [0, 0, 0, 0].
|
||||
* else return true and set the rect parameter to the bounds of the control-points
|
||||
* of the path.
|
||||
*/
|
||||
SK_API bool sk_path_get_bounds(const sk_path_t*, sk_rect_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
70
gfx/skia/skia/include/c/sk_picture.h
Normal file
70
gfx/skia/skia/include/c/sk_picture.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_picture_DEFINED
|
||||
#define sk_picture_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Create a new sk_picture_recorder_t. Its resources should be
|
||||
released with a call to sk_picture_recorder_delete().
|
||||
*/
|
||||
sk_picture_recorder_t* sk_picture_recorder_new();
|
||||
/**
|
||||
Release the memory and other resources used by this
|
||||
sk_picture_recorder_t.
|
||||
*/
|
||||
void sk_picture_recorder_delete(sk_picture_recorder_t*);
|
||||
|
||||
/**
|
||||
Returns the canvas that records the drawing commands
|
||||
|
||||
@param sk_rect_t* the cull rect used when recording this
|
||||
picture. Any drawing the falls outside of this
|
||||
rect is undefined, and may be drawn or it may not.
|
||||
*/
|
||||
sk_canvas_t* sk_picture_recorder_begin_recording(sk_picture_recorder_t*, const sk_rect_t*);
|
||||
/**
|
||||
Signal that the caller is done recording. This invalidates the
|
||||
canvas returned by begin_recording. Ownership of the sk_picture_t
|
||||
is passed to the caller, who must call sk_picture_unref() when
|
||||
they are done using it. The returned picture is immutable.
|
||||
*/
|
||||
sk_picture_t* sk_picture_recorder_end_recording(sk_picture_recorder_t*);
|
||||
|
||||
/**
|
||||
Increment the reference count on the given sk_picture_t. Must be
|
||||
balanced by a call to sk_picture_unref().
|
||||
*/
|
||||
void sk_picture_ref(sk_picture_t*);
|
||||
/**
|
||||
Decrement the reference count. If the reference count is 1 before
|
||||
the decrement, then release both the memory holding the
|
||||
sk_picture_t and any resouces it may be managing. New
|
||||
sk_picture_t are created with a reference count of 1.
|
||||
*/
|
||||
void sk_picture_unref(sk_picture_t*);
|
||||
|
||||
/**
|
||||
Returns a non-zero value unique among all pictures.
|
||||
*/
|
||||
uint32_t sk_picture_get_unique_id(sk_picture_t*);
|
||||
|
||||
/**
|
||||
Return the cull rect specified when this picture was recorded.
|
||||
*/
|
||||
sk_rect_t sk_picture_get_bounds(sk_picture_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
143
gfx/skia/skia/include/c/sk_shader.h
Normal file
143
gfx/skia/skia/include/c/sk_shader.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_shader_DEFINED
|
||||
#define sk_shader_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
void sk_shader_ref(sk_shader_t*);
|
||||
void sk_shader_unref(sk_shader_t*);
|
||||
|
||||
typedef enum {
|
||||
CLAMP_SK_SHADER_TILEMODE,
|
||||
REPEAT_SK_SHADER_TILEMODE,
|
||||
MIRROR_SK_SHADER_TILEMODE,
|
||||
} sk_shader_tilemode_t;
|
||||
|
||||
/**
|
||||
Returns a shader that generates a linear gradient between the two
|
||||
specified points.
|
||||
|
||||
@param points The start and end points for the gradient.
|
||||
@param colors The array[count] of colors, to be distributed between
|
||||
the two points
|
||||
@param colorPos May be NULL. array[count] of SkScalars, or NULL, of
|
||||
the relative position of each corresponding color
|
||||
in the colors array. If this is NULL, the the
|
||||
colors are distributed evenly between the start
|
||||
and end point. If this is not null, the values
|
||||
must begin with 0, end with 1.0, and intermediate
|
||||
values must be strictly increasing.
|
||||
@param colorCount Must be >=2. The number of colors (and pos if not
|
||||
NULL) entries.
|
||||
@param mode The tiling mode
|
||||
*/
|
||||
sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2],
|
||||
const sk_color_t colors[],
|
||||
const float colorPos[],
|
||||
int colorCount,
|
||||
sk_shader_tilemode_t tileMode,
|
||||
const sk_matrix_t* localMatrix);
|
||||
|
||||
|
||||
/**
|
||||
Returns a shader that generates a radial gradient given the center
|
||||
and radius.
|
||||
|
||||
@param center The center of the circle for this gradient
|
||||
@param radius Must be positive. The radius of the circle for this
|
||||
gradient
|
||||
@param colors The array[count] of colors, to be distributed
|
||||
between the center and edge of the circle
|
||||
@param colorPos May be NULL. The array[count] of the relative
|
||||
position of each corresponding color in the colors
|
||||
array. If this is NULL, the the colors are
|
||||
distributed evenly between the center and edge of
|
||||
the circle. If this is not null, the values must
|
||||
begin with 0, end with 1.0, and intermediate
|
||||
values must be strictly increasing.
|
||||
@param count Must be >= 2. The number of colors (and pos if not
|
||||
NULL) entries
|
||||
@param tileMode The tiling mode
|
||||
@param localMatrix May be NULL
|
||||
*/
|
||||
sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* center,
|
||||
float radius,
|
||||
const sk_color_t colors[],
|
||||
const float colorPos[],
|
||||
int colorCount,
|
||||
sk_shader_tilemode_t tileMode,
|
||||
const sk_matrix_t* localMatrix);
|
||||
|
||||
/**
|
||||
Returns a shader that generates a sweep gradient given a center.
|
||||
|
||||
@param center The coordinates of the center of the sweep
|
||||
@param colors The array[count] of colors, to be distributed around
|
||||
the center.
|
||||
@param colorPos May be NULL. The array[count] of the relative
|
||||
position of each corresponding color in the colors
|
||||
array. If this is NULL, the the colors are
|
||||
distributed evenly between the center and edge of
|
||||
the circle. If this is not null, the values must
|
||||
begin with 0, end with 1.0, and intermediate
|
||||
values must be strictly increasing.
|
||||
@param colorCount Must be >= 2. The number of colors (and pos if
|
||||
not NULL) entries
|
||||
@param localMatrix May be NULL
|
||||
*/
|
||||
sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* center,
|
||||
const sk_color_t colors[],
|
||||
const float colorPos[],
|
||||
int colorCount,
|
||||
const sk_matrix_t* localMatrix);
|
||||
|
||||
/**
|
||||
Returns a shader that generates a conical gradient given two circles, or
|
||||
returns NULL if the inputs are invalid. The gradient interprets the
|
||||
two circles according to the following HTML spec.
|
||||
http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
|
||||
|
||||
Returns a shader that generates a sweep gradient given a center.
|
||||
|
||||
@param start, startRadius Defines the first circle.
|
||||
@param end, endRadius Defines the first circle.
|
||||
@param colors The array[count] of colors, to be distributed between
|
||||
the two circles.
|
||||
@param colorPos May be NULL. The array[count] of the relative
|
||||
position of each corresponding color in the colors
|
||||
array. If this is NULL, the the colors are
|
||||
distributed evenly between the two circles. If
|
||||
this is not null, the values must begin with 0,
|
||||
end with 1.0, and intermediate values must be
|
||||
strictly increasing.
|
||||
@param colorCount Must be >= 2. The number of colors (and pos if
|
||||
not NULL) entries
|
||||
@param tileMode The tiling mode
|
||||
@param localMatrix May be NULL
|
||||
|
||||
*/
|
||||
sk_shader_t* sk_shader_new_two_point_conical_gradient(
|
||||
const sk_point_t* start,
|
||||
float startRadius,
|
||||
const sk_point_t* end,
|
||||
float endRadius,
|
||||
const sk_color_t colors[],
|
||||
const float colorPos[],
|
||||
int colorCount,
|
||||
sk_shader_tilemode_t tileMode,
|
||||
const sk_matrix_t* localMatrix);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
73
gfx/skia/skia/include/c/sk_surface.h
Normal file
73
gfx/skia/skia/include/c/sk_surface.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_surface_DEFINED
|
||||
#define sk_surface_DEFINED
|
||||
|
||||
#include "sk_types.h"
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
/**
|
||||
Return a new surface, with the memory for the pixels automatically
|
||||
allocated. If the requested surface cannot be created, or the
|
||||
request is not a supported configuration, NULL will be returned.
|
||||
|
||||
@param sk_imageinfo_t* Specify the width, height, color type, and
|
||||
alpha type for the surface.
|
||||
|
||||
@param sk_surfaceprops_t* If not NULL, specify additional non-default
|
||||
properties of the surface.
|
||||
*/
|
||||
SK_API sk_surface_t* sk_surface_new_raster(const sk_imageinfo_t*, const sk_surfaceprops_t*);
|
||||
|
||||
/**
|
||||
Create a new surface which will draw into the specified pixels
|
||||
with the specified rowbytes. If the requested surface cannot be
|
||||
created, or the request is not a supported configuration, NULL
|
||||
will be returned.
|
||||
|
||||
@param sk_imageinfo_t* Specify the width, height, color type, and
|
||||
alpha type for the surface.
|
||||
@param void* pixels Specify the location in memory where the
|
||||
destination pixels are. This memory must
|
||||
outlast this surface.
|
||||
@param size_t rowBytes Specify the difference, in bytes, between
|
||||
each adjacent row. Should be at least
|
||||
(width * sizeof(one pixel)).
|
||||
@param sk_surfaceprops_t* If not NULL, specify additional non-default
|
||||
properties of the surface.
|
||||
*/
|
||||
SK_API sk_surface_t* sk_surface_new_raster_direct(const sk_imageinfo_t*,
|
||||
void* pixels, size_t rowBytes,
|
||||
const sk_surfaceprops_t* props);
|
||||
|
||||
/**
|
||||
Decrement the reference count. If the reference count is 1 before
|
||||
the decrement, then release both the memory holding the
|
||||
sk_surface_t and any pixel memory it may be managing. New
|
||||
sk_surface_t are created with a reference count of 1.
|
||||
*/
|
||||
SK_API void sk_surface_unref(sk_surface_t*);
|
||||
|
||||
/**
|
||||
* Return the canvas associated with this surface. Note: the canvas is owned by the surface,
|
||||
* so the returned object is only valid while the owning surface is valid.
|
||||
*/
|
||||
SK_API sk_canvas_t* sk_surface_get_canvas(sk_surface_t*);
|
||||
|
||||
/**
|
||||
* Call sk_image_unref() when the returned image is no longer used.
|
||||
*/
|
||||
SK_API sk_image_t* sk_surface_new_image_snapshot(sk_surface_t*);
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
205
gfx/skia/skia/include/c/sk_types.h
Normal file
205
gfx/skia/skia/include/c/sk_types.h
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
|
||||
// DO NOT USE -- FOR INTERNAL TESTING ONLY
|
||||
|
||||
#ifndef sk_types_DEFINED
|
||||
#define sk_types_DEFINED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define SK_C_PLUS_PLUS_BEGIN_GUARD extern "C" {
|
||||
#define SK_C_PLUS_PLUS_END_GUARD }
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#define SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
#define SK_C_PLUS_PLUS_END_GUARD
|
||||
#endif
|
||||
|
||||
#ifndef SK_API
|
||||
#define SK_API
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SK_C_PLUS_PLUS_BEGIN_GUARD
|
||||
|
||||
typedef uint32_t sk_color_t;
|
||||
|
||||
/* This macro assumes all arguments are >=0 and <=255. */
|
||||
#define sk_color_set_argb(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
|
||||
#define sk_color_get_a(c) (((c) >> 24) & 0xFF)
|
||||
#define sk_color_get_r(c) (((c) >> 16) & 0xFF)
|
||||
#define sk_color_get_g(c) (((c) >> 8) & 0xFF)
|
||||
#define sk_color_get_b(c) (((c) >> 0) & 0xFF)
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN_SK_COLORTYPE,
|
||||
RGBA_8888_SK_COLORTYPE,
|
||||
BGRA_8888_SK_COLORTYPE,
|
||||
ALPHA_8_SK_COLORTYPE,
|
||||
} sk_colortype_t;
|
||||
|
||||
typedef enum {
|
||||
OPAQUE_SK_ALPHATYPE,
|
||||
PREMUL_SK_ALPHATYPE,
|
||||
UNPREMUL_SK_ALPHATYPE,
|
||||
} sk_alphatype_t;
|
||||
|
||||
typedef enum {
|
||||
INTERSECT_SK_CLIPTYPE,
|
||||
DIFFERENCE_SK_CLIPTYPE,
|
||||
} sk_cliptype_t;
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN_SK_PIXELGEOMETRY,
|
||||
RGB_H_SK_PIXELGEOMETRY,
|
||||
BGR_H_SK_PIXELGEOMETRY,
|
||||
RGB_V_SK_PIXELGEOMETRY,
|
||||
BGR_V_SK_PIXELGEOMETRY,
|
||||
} sk_pixelgeometry_t;
|
||||
|
||||
/**
|
||||
Return the default sk_colortype_t; this is operating-system dependent.
|
||||
*/
|
||||
SK_API sk_colortype_t sk_colortype_get_default_8888();
|
||||
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
sk_colortype_t colorType;
|
||||
sk_alphatype_t alphaType;
|
||||
} sk_imageinfo_t;
|
||||
|
||||
typedef struct {
|
||||
sk_pixelgeometry_t pixelGeometry;
|
||||
} sk_surfaceprops_t;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} sk_point_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
} sk_irect_t;
|
||||
|
||||
typedef struct {
|
||||
float left;
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
} sk_rect_t;
|
||||
|
||||
typedef struct {
|
||||
float mat[9];
|
||||
} sk_matrix_t;
|
||||
|
||||
/**
|
||||
A sk_canvas_t encapsulates all of the state about drawing into a
|
||||
destination This includes a reference to the destination itself,
|
||||
and a stack of matrix/clip values.
|
||||
*/
|
||||
typedef struct sk_canvas_t sk_canvas_t;
|
||||
/**
|
||||
A sk_data_ holds an immutable data buffer.
|
||||
*/
|
||||
typedef struct sk_data_t sk_data_t;
|
||||
/**
|
||||
A sk_image_t is an abstraction for drawing a rectagle of pixels.
|
||||
The content of the image is always immutable, though the actual
|
||||
storage may change, if for example that image can be re-created via
|
||||
encoded data or other means.
|
||||
*/
|
||||
typedef struct sk_image_t sk_image_t;
|
||||
/**
|
||||
A sk_maskfilter_t is an object that perform transformations on an
|
||||
alpha-channel mask before drawing it; it may be installed into a
|
||||
sk_paint_t. Each time a primitive is drawn, it is first
|
||||
scan-converted into a alpha mask, which os handed to the
|
||||
maskfilter, which may create a new mask is to render into the
|
||||
destination.
|
||||
*/
|
||||
typedef struct sk_maskfilter_t sk_maskfilter_t;
|
||||
/**
|
||||
A sk_paint_t holds the style and color information about how to
|
||||
draw geometries, text and bitmaps.
|
||||
*/
|
||||
typedef struct sk_paint_t sk_paint_t;
|
||||
/**
|
||||
A sk_path_t encapsulates compound (multiple contour) geometric
|
||||
paths consisting of straight line segments, quadratic curves, and
|
||||
cubic curves.
|
||||
*/
|
||||
typedef struct sk_path_t sk_path_t;
|
||||
/**
|
||||
A sk_picture_t holds recorded canvas drawing commands to be played
|
||||
back at a later time.
|
||||
*/
|
||||
typedef struct sk_picture_t sk_picture_t;
|
||||
/**
|
||||
A sk_picture_recorder_t holds a sk_canvas_t that records commands
|
||||
to create a sk_picture_t.
|
||||
*/
|
||||
typedef struct sk_picture_recorder_t sk_picture_recorder_t;
|
||||
/**
|
||||
A sk_shader_t specifies the source color(s) for what is being drawn. If a
|
||||
paint has no shader, then the paint's color is used. If the paint
|
||||
has a shader, then the shader's color(s) are use instead, but they
|
||||
are modulated by the paint's alpha.
|
||||
*/
|
||||
typedef struct sk_shader_t sk_shader_t;
|
||||
/**
|
||||
A sk_surface_t holds the destination for drawing to a canvas. For
|
||||
raster drawing, the destination is an array of pixels in memory.
|
||||
For GPU drawing, the destination is a texture or a framebuffer.
|
||||
*/
|
||||
typedef struct sk_surface_t sk_surface_t;
|
||||
|
||||
typedef enum {
|
||||
CLEAR_SK_XFERMODE_MODE,
|
||||
SRC_SK_XFERMODE_MODE,
|
||||
DST_SK_XFERMODE_MODE,
|
||||
SRCOVER_SK_XFERMODE_MODE,
|
||||
DSTOVER_SK_XFERMODE_MODE,
|
||||
SRCIN_SK_XFERMODE_MODE,
|
||||
DSTIN_SK_XFERMODE_MODE,
|
||||
SRCOUT_SK_XFERMODE_MODE,
|
||||
DSTOUT_SK_XFERMODE_MODE,
|
||||
SRCATOP_SK_XFERMODE_MODE,
|
||||
DSTATOP_SK_XFERMODE_MODE,
|
||||
XOR_SK_XFERMODE_MODE,
|
||||
PLUS_SK_XFERMODE_MODE,
|
||||
MODULATE_SK_XFERMODE_MODE,
|
||||
SCREEN_SK_XFERMODE_MODE,
|
||||
OVERLAY_SK_XFERMODE_MODE,
|
||||
DARKEN_SK_XFERMODE_MODE,
|
||||
LIGHTEN_SK_XFERMODE_MODE,
|
||||
COLORDODGE_SK_XFERMODE_MODE,
|
||||
COLORBURN_SK_XFERMODE_MODE,
|
||||
HARDLIGHT_SK_XFERMODE_MODE,
|
||||
SOFTLIGHT_SK_XFERMODE_MODE,
|
||||
DIFFERENCE_SK_XFERMODE_MODE,
|
||||
EXCLUSION_SK_XFERMODE_MODE,
|
||||
MULTIPLY_SK_XFERMODE_MODE,
|
||||
HUE_SK_XFERMODE_MODE,
|
||||
SATURATION_SK_XFERMODE_MODE,
|
||||
COLOR_SK_XFERMODE_MODE,
|
||||
LUMINOSITY_SK_XFERMODE_MODE,
|
||||
} sk_xfermode_mode_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SK_C_PLUS_PLUS_END_GUARD
|
||||
|
||||
#endif
|
230
gfx/skia/skia/include/codec/SkAndroidCodec.h
Normal file
230
gfx/skia/skia/include/codec/SkAndroidCodec.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAndroidCodec_DEFINED
|
||||
#define SkAndroidCodec_DEFINED
|
||||
|
||||
#include "SkCodec.h"
|
||||
#include "SkEncodedFormat.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Abstract interface defining image codec functionality that is necessary for
|
||||
* Android.
|
||||
*/
|
||||
class SkAndroidCodec : SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* If this stream represents an encoded image that we know how to decode,
|
||||
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* The SkPngChunkReader handles unknown chunks in PNGs.
|
||||
* See SkCodec.h for more details.
|
||||
*
|
||||
* If NULL is returned, the stream is deleted immediately. Otherwise, the
|
||||
* SkCodec takes ownership of it, and will delete it when done with it.
|
||||
*/
|
||||
static SkAndroidCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL);
|
||||
|
||||
/**
|
||||
* If this data represents an encoded image that we know how to decode,
|
||||
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* The SkPngChunkReader handles unknown chunks in PNGs.
|
||||
* See SkCodec.h for more details.
|
||||
*
|
||||
* Will take a ref if it returns a codec, else will not affect the data.
|
||||
*/
|
||||
static SkAndroidCodec* NewFromData(SkData*, SkPngChunkReader* = NULL);
|
||||
|
||||
virtual ~SkAndroidCodec() {}
|
||||
|
||||
|
||||
const SkImageInfo& getInfo() const { return fInfo; }
|
||||
|
||||
/**
|
||||
* Format of the encoded data.
|
||||
*/
|
||||
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the scaled output image, for an input
|
||||
* sampleSize.
|
||||
*
|
||||
* When the sample size divides evenly into the original dimensions, the
|
||||
* scaled output dimensions will simply be equal to the original
|
||||
* dimensions divided by the sample size.
|
||||
*
|
||||
* When the sample size does not divide even into the original
|
||||
* dimensions, the codec may round up or down, depending on what is most
|
||||
* efficient to decode.
|
||||
*
|
||||
* Finally, the codec will always recommend a non-zero output, so the output
|
||||
* dimension will always be one if the sampleSize is greater than the
|
||||
* original dimension.
|
||||
*/
|
||||
SkISize getSampledDimensions(int sampleSize) const;
|
||||
|
||||
/**
|
||||
* Return (via desiredSubset) a subset which can decoded from this codec,
|
||||
* or false if the input subset is invalid.
|
||||
*
|
||||
* @param desiredSubset in/out parameter
|
||||
* As input, a desired subset of the original bounds
|
||||
* (as specified by getInfo).
|
||||
* As output, if true is returned, desiredSubset may
|
||||
* have been modified to a subset which is
|
||||
* supported. Although a particular change may have
|
||||
* been made to desiredSubset to create something
|
||||
* supported, it is possible other changes could
|
||||
* result in a valid subset. If false is returned,
|
||||
* desiredSubset's value is undefined.
|
||||
* @return true If the input desiredSubset is valid.
|
||||
* desiredSubset may be modified to a subset
|
||||
* supported by the codec.
|
||||
* false If desiredSubset is invalid (NULL or not fully
|
||||
* contained within the image).
|
||||
*/
|
||||
bool getSupportedSubset(SkIRect* desiredSubset) const;
|
||||
// TODO: Rename SkCodec::getValidSubset() to getSupportedSubset()
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the scaled, partial output image, for an
|
||||
* input sampleSize and subset.
|
||||
*
|
||||
* @param sampleSize Factor to scale down by.
|
||||
* @param subset Must be a valid subset of the original image
|
||||
* dimensions and a subset supported by SkAndroidCodec.
|
||||
* getSubset() can be used to obtain a subset supported
|
||||
* by SkAndroidCodec.
|
||||
* @return Size of the scaled partial image. Or zero size
|
||||
* if either of the inputs is invalid.
|
||||
*/
|
||||
SkISize getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const;
|
||||
|
||||
/**
|
||||
* Additional options to pass to getAndroidPixels().
|
||||
*/
|
||||
// FIXME: It's a bit redundant to name these AndroidOptions when this class is already
|
||||
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
|
||||
// these Options when SkCodec has a slightly different set of Options. Maybe these
|
||||
// should be DecodeOptions or SamplingOptions?
|
||||
struct AndroidOptions {
|
||||
AndroidOptions()
|
||||
: fZeroInitialized(SkCodec::kNo_ZeroInitialized)
|
||||
, fSubset(nullptr)
|
||||
, fColorPtr(nullptr)
|
||||
, fColorCount(nullptr)
|
||||
, fSampleSize(1)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Indicates is destination pixel memory is zero initialized.
|
||||
*/
|
||||
SkCodec::ZeroInitialized fZeroInitialized;
|
||||
|
||||
/**
|
||||
* If not NULL, represents a subset of the original image to decode.
|
||||
*
|
||||
* Must be within the bounds returned by getInfo().
|
||||
*
|
||||
* If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left
|
||||
* values must be even.
|
||||
*/
|
||||
SkIRect* fSubset;
|
||||
|
||||
/**
|
||||
* If the client has requested a decode to kIndex8_SkColorType
|
||||
* (specified in the SkImageInfo), then the caller must provide
|
||||
* storage for up to 256 SkPMColor values in fColorPtr. On success,
|
||||
* the codec must copy N colors into that storage, (where N is the
|
||||
* logical number of table entries) and set fColorCount to N.
|
||||
*
|
||||
* If the client does not request kIndex8_SkColorType, then the last
|
||||
* two parameters may be NULL. If fColorCount is not null, it will be
|
||||
* set to 0.
|
||||
*/
|
||||
SkPMColor* fColorPtr;
|
||||
int* fColorCount;
|
||||
|
||||
/**
|
||||
* The client may provide an integer downscale factor for the decode.
|
||||
* The codec may implement this downscaling by sampling or another
|
||||
* method if it is more efficient.
|
||||
*/
|
||||
int fSampleSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode into the given pixels, a block of memory of size at
|
||||
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
|
||||
* bytesPerPixel)
|
||||
*
|
||||
* Repeated calls to this function should give the same results,
|
||||
* allowing the PixelRef to be immutable.
|
||||
*
|
||||
* @param info A description of the format (config, size)
|
||||
* expected by the caller. This can simply be identical
|
||||
* to the info returned by getInfo().
|
||||
*
|
||||
* This contract also allows the caller to specify
|
||||
* different output-configs, which the implementation can
|
||||
* decide to support or not.
|
||||
*
|
||||
* A size that does not match getInfo() implies a request
|
||||
* to scale or subset. If the codec cannot perform this
|
||||
* scaling or subsetting, it will return an error code.
|
||||
*
|
||||
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
||||
* SkPMColor values in options->fColorPtr. On success the codec must copy N colors into
|
||||
* that storage, (where N is the logical number of table entries) and set
|
||||
* options->fColorCount to N.
|
||||
*
|
||||
* If info is not kIndex8_SkColorType, options->fColorPtr and options->fColorCount may
|
||||
* be nullptr.
|
||||
*
|
||||
* The AndroidOptions object is also used to specify any requested scaling or subsetting
|
||||
* using options->fSampleSize and options->fSubset.
|
||||
*
|
||||
* @return Result kSuccess, or another value explaining the type of failure.
|
||||
*/
|
||||
// FIXME: It's a bit redundant to name this getAndroidPixels() when this class is already
|
||||
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
|
||||
// this getPixels() when it is a slightly different API than SkCodec's getPixels().
|
||||
// Maybe this should be decode() or decodeSubset()?
|
||||
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const AndroidOptions* options);
|
||||
|
||||
/**
|
||||
* Simplified version of getAndroidPixels() where we supply the default AndroidOptions.
|
||||
*
|
||||
* This will return an error if the info is kIndex_8_SkColorType and also will not perform
|
||||
* any scaling or subsetting.
|
||||
*/
|
||||
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
|
||||
protected:
|
||||
|
||||
SkAndroidCodec(const SkImageInfo&);
|
||||
|
||||
virtual SkEncodedFormat onGetEncodedFormat() const = 0;
|
||||
|
||||
virtual SkISize onGetSampledDimensions(int sampleSize) const = 0;
|
||||
|
||||
virtual bool onGetSupportedSubset(SkIRect* desiredSubset) const = 0;
|
||||
|
||||
virtual SkCodec::Result onGetAndroidPixels(const SkImageInfo& info, void* pixels,
|
||||
size_t rowBytes, const AndroidOptions& options) = 0;
|
||||
|
||||
private:
|
||||
|
||||
// This will always be a reference to the info that is contained by the
|
||||
// embedded SkCodec.
|
||||
const SkImageInfo& fInfo;
|
||||
};
|
||||
#endif // SkAndroidCodec_DEFINED
|
614
gfx/skia/skia/include/codec/SkCodec.h
Normal file
614
gfx/skia/skia/include/codec/SkCodec.h
Normal file
@ -0,0 +1,614 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCodec_DEFINED
|
||||
#define SkCodec_DEFINED
|
||||
|
||||
#include "../private/SkTemplates.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkEncodedFormat.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkSize.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkData;
|
||||
class SkPngChunkReader;
|
||||
class SkSampler;
|
||||
|
||||
/**
|
||||
* Abstraction layer directly on top of an image codec.
|
||||
*/
|
||||
class SkCodec : SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* If this stream represents an encoded image that we know how to decode,
|
||||
* return an SkCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* If the SkPngChunkReader is not NULL then:
|
||||
* If the image is not a PNG, the SkPngChunkReader will be ignored.
|
||||
* If the image is a PNG, the SkPngChunkReader will be reffed.
|
||||
* If the PNG has unknown chunks, the SkPngChunkReader will be used
|
||||
* to handle these chunks. SkPngChunkReader will be called to read
|
||||
* any unknown chunk at any point during the creation of the codec
|
||||
* or the decode. Note that if SkPngChunkReader fails to read a
|
||||
* chunk, this could result in a failure to create the codec or a
|
||||
* failure to decode the image.
|
||||
* If the PNG does not contain unknown chunks, the SkPngChunkReader
|
||||
* will not be used or modified.
|
||||
*
|
||||
* If NULL is returned, the stream is deleted immediately. Otherwise, the
|
||||
* SkCodec takes ownership of it, and will delete it when done with it.
|
||||
*/
|
||||
static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL);
|
||||
|
||||
/**
|
||||
* If this data represents an encoded image that we know how to decode,
|
||||
* return an SkCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* If the SkPngChunkReader is not NULL then:
|
||||
* If the image is not a PNG, the SkPngChunkReader will be ignored.
|
||||
* If the image is a PNG, the SkPngChunkReader will be reffed.
|
||||
* If the PNG has unknown chunks, the SkPngChunkReader will be used
|
||||
* to handle these chunks. SkPngChunkReader will be called to read
|
||||
* any unknown chunk at any point during the creation of the codec
|
||||
* or the decode. Note that if SkPngChunkReader fails to read a
|
||||
* chunk, this could result in a failure to create the codec or a
|
||||
* failure to decode the image.
|
||||
* If the PNG does not contain unknown chunks, the SkPngChunkReader
|
||||
* will not be used or modified.
|
||||
*
|
||||
* Will take a ref if it returns a codec, else will not affect the data.
|
||||
*/
|
||||
static SkCodec* NewFromData(SkData*, SkPngChunkReader* = NULL);
|
||||
|
||||
virtual ~SkCodec();
|
||||
|
||||
/**
|
||||
* Return the ImageInfo associated with this codec.
|
||||
*/
|
||||
const SkImageInfo& getInfo() const { return fSrcInfo; }
|
||||
|
||||
/**
|
||||
* Return a size that approximately supports the desired scale factor.
|
||||
* The codec may not be able to scale efficiently to the exact scale
|
||||
* factor requested, so return a size that approximates that scale.
|
||||
* The returned value is the codec's suggestion for the closest valid
|
||||
* scale that it can natively support
|
||||
*/
|
||||
SkISize getScaledDimensions(float desiredScale) const {
|
||||
// Negative and zero scales are errors.
|
||||
SkASSERT(desiredScale > 0.0f);
|
||||
if (desiredScale <= 0.0f) {
|
||||
return SkISize::Make(0, 0);
|
||||
}
|
||||
|
||||
// Upscaling is not supported. Return the original size if the client
|
||||
// requests an upscale.
|
||||
if (desiredScale >= 1.0f) {
|
||||
return this->getInfo().dimensions();
|
||||
}
|
||||
return this->onGetScaledDimensions(desiredScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return (via desiredSubset) a subset which can decoded from this codec,
|
||||
* or false if this codec cannot decode subsets or anything similar to
|
||||
* desiredSubset.
|
||||
*
|
||||
* @param desiredSubset In/out parameter. As input, a desired subset of
|
||||
* the original bounds (as specified by getInfo). If true is returned,
|
||||
* desiredSubset may have been modified to a subset which is
|
||||
* supported. Although a particular change may have been made to
|
||||
* desiredSubset to create something supported, it is possible other
|
||||
* changes could result in a valid subset.
|
||||
* If false is returned, desiredSubset's value is undefined.
|
||||
* @return true if this codec supports decoding desiredSubset (as
|
||||
* returned, potentially modified)
|
||||
*/
|
||||
bool getValidSubset(SkIRect* desiredSubset) const {
|
||||
return this->onGetValidSubset(desiredSubset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format of the encoded data.
|
||||
*/
|
||||
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
|
||||
|
||||
/**
|
||||
* Used to describe the result of a call to getPixels().
|
||||
*
|
||||
* Result is the union of possible results from subclasses.
|
||||
*/
|
||||
enum Result {
|
||||
/**
|
||||
* General return value for success.
|
||||
*/
|
||||
kSuccess,
|
||||
/**
|
||||
* The input is incomplete. A partial image was generated.
|
||||
*/
|
||||
kIncompleteInput,
|
||||
/**
|
||||
* The generator cannot convert to match the request, ignoring
|
||||
* dimensions.
|
||||
*/
|
||||
kInvalidConversion,
|
||||
/**
|
||||
* The generator cannot scale to requested size.
|
||||
*/
|
||||
kInvalidScale,
|
||||
/**
|
||||
* Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
|
||||
* too small, etc.
|
||||
*/
|
||||
kInvalidParameters,
|
||||
/**
|
||||
* The input did not contain a valid image.
|
||||
*/
|
||||
kInvalidInput,
|
||||
/**
|
||||
* Fulfilling this request requires rewinding the input, which is not
|
||||
* supported for this input.
|
||||
*/
|
||||
kCouldNotRewind,
|
||||
/**
|
||||
* This method is not implemented by this codec.
|
||||
* FIXME: Perhaps this should be kUnsupported?
|
||||
*/
|
||||
kUnimplemented,
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not the memory passed to getPixels is zero initialized.
|
||||
*/
|
||||
enum ZeroInitialized {
|
||||
/**
|
||||
* The memory passed to getPixels is zero initialized. The SkCodec
|
||||
* may take advantage of this by skipping writing zeroes.
|
||||
*/
|
||||
kYes_ZeroInitialized,
|
||||
/**
|
||||
* The memory passed to getPixels has not been initialized to zero,
|
||||
* so the SkCodec must write all zeroes to memory.
|
||||
*
|
||||
* This is the default. It will be used if no Options struct is used.
|
||||
*/
|
||||
kNo_ZeroInitialized,
|
||||
};
|
||||
|
||||
/**
|
||||
* Additional options to pass to getPixels.
|
||||
*/
|
||||
struct Options {
|
||||
Options()
|
||||
: fZeroInitialized(kNo_ZeroInitialized)
|
||||
, fSubset(NULL)
|
||||
{}
|
||||
|
||||
ZeroInitialized fZeroInitialized;
|
||||
/**
|
||||
* If not NULL, represents a subset of the original image to decode.
|
||||
* Must be within the bounds returned by getInfo().
|
||||
* If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
|
||||
* currently supports subsets), the top and left values must be even.
|
||||
*
|
||||
* In getPixels, we will attempt to decode the exact rectangular
|
||||
* subset specified by fSubset.
|
||||
*
|
||||
* In a scanline decode, it does not make sense to specify a subset
|
||||
* top or subset height, since the client already controls which rows
|
||||
* to get and which rows to skip. During scanline decodes, we will
|
||||
* require that the subset top be zero and the subset height be equal
|
||||
* to the full height. We will, however, use the values of
|
||||
* subset left and subset width to decode partial scanlines on calls
|
||||
* to getScanlines().
|
||||
*/
|
||||
SkIRect* fSubset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode into the given pixels, a block of memory of size at
|
||||
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
|
||||
* bytesPerPixel)
|
||||
*
|
||||
* Repeated calls to this function should give the same results,
|
||||
* allowing the PixelRef to be immutable.
|
||||
*
|
||||
* @param info A description of the format (config, size)
|
||||
* expected by the caller. This can simply be identical
|
||||
* to the info returned by getInfo().
|
||||
*
|
||||
* This contract also allows the caller to specify
|
||||
* different output-configs, which the implementation can
|
||||
* decide to support or not.
|
||||
*
|
||||
* A size that does not match getInfo() implies a request
|
||||
* to scale. If the generator cannot perform this scale,
|
||||
* it will return kInvalidScale.
|
||||
*
|
||||
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
||||
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
|
||||
* (where N is the logical number of table entries) and set ctableCount to N.
|
||||
*
|
||||
* If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
|
||||
* is not null, it will be set to 0.
|
||||
*
|
||||
* If a scanline decode is in progress, scanline mode will end, requiring the client to call
|
||||
* startScanlineDecode() in order to return to decoding scanlines.
|
||||
*
|
||||
* @return Result kSuccess, or another value explaining the type of failure.
|
||||
*/
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*,
|
||||
SkPMColor ctable[], int* ctableCount);
|
||||
|
||||
/**
|
||||
* Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
|
||||
* uses the default Options.
|
||||
*/
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Some images may initially report that they have alpha due to the format
|
||||
* of the encoded data, but then never use any colors which have alpha
|
||||
* less than 100%. This function can be called *after* decoding to
|
||||
* determine if such an image truly had alpha. Calling it before decoding
|
||||
* is undefined.
|
||||
* FIXME: see skbug.com/3582.
|
||||
*/
|
||||
bool reallyHasAlpha() const {
|
||||
return this->onReallyHasAlpha();
|
||||
}
|
||||
|
||||
/**
|
||||
* The remaining functions revolve around decoding scanlines.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare for a scanline decode with the specified options.
|
||||
*
|
||||
* After this call, this class will be ready to decode the first scanline.
|
||||
*
|
||||
* This must be called in order to call getScanlines or skipScanlines.
|
||||
*
|
||||
* This may require rewinding the stream.
|
||||
*
|
||||
* Not all SkCodecs support this.
|
||||
*
|
||||
* @param dstInfo Info of the destination. If the dimensions do not match
|
||||
* those of getInfo, this implies a scale.
|
||||
* @param options Contains decoding options, including if memory is zero
|
||||
* initialized.
|
||||
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
||||
* kIndex8, this should be non-NULL and have enough storage for 256
|
||||
* colors. The color table will be populated after decoding the palette.
|
||||
* @param ctableCount A pointer to the size of the color table. When
|
||||
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
||||
* be modified to the true size of the color table (<= 256) after
|
||||
* decoding the palette.
|
||||
* @return Enum representing success or reason for failure.
|
||||
*/
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options,
|
||||
SkPMColor ctable[], int* ctableCount);
|
||||
|
||||
/**
|
||||
* Simplified version of startScanlineDecode() that asserts that info is NOT
|
||||
* kIndex8_SkColorType and uses the default Options.
|
||||
*/
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo);
|
||||
|
||||
/**
|
||||
* Write the next countLines scanlines into dst.
|
||||
*
|
||||
* Not valid to call before calling startScanlineDecode().
|
||||
*
|
||||
* @param dst Must be non-null, and large enough to hold countLines
|
||||
* scanlines of size rowBytes.
|
||||
* @param countLines Number of lines to write.
|
||||
* @param rowBytes Number of bytes per row. Must be large enough to hold
|
||||
* a scanline based on the SkImageInfo used to create this object.
|
||||
* @return the number of lines successfully decoded. If this value is
|
||||
* less than countLines, this will fill the remaining lines with a
|
||||
* default value.
|
||||
*/
|
||||
int getScanlines(void* dst, int countLines, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Skip count scanlines.
|
||||
*
|
||||
* Not valid to call before calling startScanlineDecode().
|
||||
*
|
||||
* The default version just calls onGetScanlines and discards the dst.
|
||||
* NOTE: If skipped lines are the only lines with alpha, this default
|
||||
* will make reallyHasAlpha return true, when it could have returned
|
||||
* false.
|
||||
*
|
||||
* @return true if the scanlines were successfully skipped
|
||||
* false on failure, possible reasons for failure include:
|
||||
* An incomplete input image stream.
|
||||
* Calling this function before calling startScanlineDecode().
|
||||
* If countLines is less than zero or so large that it moves
|
||||
* the current scanline past the end of the image.
|
||||
*/
|
||||
bool skipScanlines(int countLines);
|
||||
|
||||
/**
|
||||
* The order in which rows are output from the scanline decoder is not the
|
||||
* same for all variations of all image types. This explains the possible
|
||||
* output row orderings.
|
||||
*/
|
||||
enum SkScanlineOrder {
|
||||
/*
|
||||
* By far the most common, this indicates that the image can be decoded
|
||||
* reliably using the scanline decoder, and that rows will be output in
|
||||
* the logical order.
|
||||
*/
|
||||
kTopDown_SkScanlineOrder,
|
||||
|
||||
/*
|
||||
* This indicates that the scanline decoder reliably outputs rows, but
|
||||
* they will be returned in reverse order. If the scanline format is
|
||||
* kBottomUp, the nextScanline() API can be used to determine the actual
|
||||
* y-coordinate of the next output row, but the client is not forced
|
||||
* to take advantage of this, given that it's not too tough to keep
|
||||
* track independently.
|
||||
*
|
||||
* For full image decodes, it is safe to get all of the scanlines at
|
||||
* once, since the decoder will handle inverting the rows as it
|
||||
* decodes.
|
||||
*
|
||||
* For subset decodes and sampling, it is simplest to get and skip
|
||||
* scanlines one at a time, using the nextScanline() API. It is
|
||||
* possible to ask for larger chunks at a time, but this should be used
|
||||
* with caution. As with full image decodes, the decoder will handle
|
||||
* inverting the requested rows, but rows will still be delivered
|
||||
* starting from the bottom of the image.
|
||||
*
|
||||
* Upside down bmps are an example.
|
||||
*/
|
||||
kBottomUp_SkScanlineOrder,
|
||||
|
||||
/*
|
||||
* This indicates that the scanline decoder reliably outputs rows, but
|
||||
* they will not be in logical order. If the scanline format is
|
||||
* kOutOfOrder, the nextScanline() API should be used to determine the
|
||||
* actual y-coordinate of the next output row.
|
||||
*
|
||||
* For this scanline ordering, it is advisable to get and skip
|
||||
* scanlines one at a time.
|
||||
*
|
||||
* Interlaced gifs are an example.
|
||||
*/
|
||||
kOutOfOrder_SkScanlineOrder,
|
||||
|
||||
/*
|
||||
* Indicates that the entire image must be decoded in order to output
|
||||
* any amount of scanlines. In this case, it is a REALLY BAD IDEA to
|
||||
* request scanlines 1-by-1 or in small chunks. The client should
|
||||
* determine which scanlines are needed and ask for all of them in
|
||||
* a single call to getScanlines().
|
||||
*
|
||||
* Interlaced pngs are an example.
|
||||
*/
|
||||
kNone_SkScanlineOrder,
|
||||
};
|
||||
|
||||
/**
|
||||
* An enum representing the order in which scanlines will be returned by
|
||||
* the scanline decoder.
|
||||
*/
|
||||
SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
|
||||
|
||||
/**
|
||||
* Returns the y-coordinate of the next row to be returned by the scanline
|
||||
* decoder.
|
||||
*
|
||||
* This will equal fCurrScanline, except in the case of strangely
|
||||
* encoded image types (bottom-up bmps, interlaced gifs).
|
||||
*
|
||||
* Results are undefined when not in scanline decoding mode.
|
||||
*/
|
||||
int nextScanline() const { return this->outputScanline(fCurrScanline); }
|
||||
|
||||
/**
|
||||
* Returns the output y-coordinate of the row that corresponds to an input
|
||||
* y-coordinate. The input y-coordinate represents where the scanline
|
||||
* is located in the encoded data.
|
||||
*
|
||||
* This will equal inputScanline, except in the case of strangely
|
||||
* encoded image types (bottom-up bmps, interlaced gifs).
|
||||
*/
|
||||
int outputScanline(int inputScanline) const;
|
||||
|
||||
protected:
|
||||
SkCodec(const SkImageInfo&, SkStream*);
|
||||
|
||||
virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
|
||||
// By default, scaling is not supported.
|
||||
return this->getInfo().dimensions();
|
||||
}
|
||||
|
||||
// FIXME: What to do about subsets??
|
||||
/**
|
||||
* Subclasses should override if they support dimensions other than the
|
||||
* srcInfo's.
|
||||
*/
|
||||
virtual bool onDimensionsSupported(const SkISize&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual SkEncodedFormat onGetEncodedFormat() const = 0;
|
||||
|
||||
/**
|
||||
* @param rowsDecoded When the encoded image stream is incomplete, this function
|
||||
* will return kIncompleteInput and rowsDecoded will be set to
|
||||
* the number of scanlines that were successfully decoded.
|
||||
* This will allow getPixels() to fill the uninitialized memory.
|
||||
*/
|
||||
virtual Result onGetPixels(const SkImageInfo& info,
|
||||
void* pixels, size_t rowBytes, const Options&,
|
||||
SkPMColor ctable[], int* ctableCount,
|
||||
int* rowsDecoded) = 0;
|
||||
|
||||
virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
|
||||
// By default, subsets are not supported.
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool onReallyHasAlpha() const { return false; }
|
||||
|
||||
/**
|
||||
* If the stream was previously read, attempt to rewind.
|
||||
*
|
||||
* If the stream needed to be rewound, call onRewind.
|
||||
* @returns true if the codec is at the right position and can be used.
|
||||
* false if there was a failure to rewind.
|
||||
*
|
||||
* This is called by getPixels() and start(). Subclasses may call if they
|
||||
* need to rewind at another time.
|
||||
*/
|
||||
bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
|
||||
|
||||
/**
|
||||
* Called by rewindIfNeeded, if the stream needed to be rewound.
|
||||
*
|
||||
* Subclasses should do any set up needed after a rewind.
|
||||
*/
|
||||
virtual bool onRewind() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
|
||||
* scanlines. This allows the subclass to indicate what value to fill with.
|
||||
*
|
||||
* @param colorType Destination color type.
|
||||
* @param alphaType Destination alpha type.
|
||||
* @return The value with which to fill uninitialized pixels.
|
||||
*
|
||||
* Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
|
||||
* an 8-bit gray color, or an 8-bit index into a color table, depending on the color
|
||||
* type.
|
||||
*/
|
||||
uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const {
|
||||
return this->onGetFillValue(colorType, alphaType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some subclasses will override this function, but this is a useful default for the color
|
||||
* types that we support. Note that for color types that do not use the full 32-bits,
|
||||
* we will simply take the low bits of the fill value.
|
||||
*
|
||||
* kN32_SkColorType: Transparent or Black
|
||||
* kRGB_565_SkColorType: Black
|
||||
* kGray_8_SkColorType: Black
|
||||
* kIndex_8_SkColorType: First color in color table
|
||||
*/
|
||||
virtual uint32_t onGetFillValue(SkColorType /*colorType*/, SkAlphaType alphaType) const {
|
||||
return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSPARENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get method for the input stream
|
||||
*/
|
||||
SkStream* stream() {
|
||||
return fStream.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* The remaining functions revolve around decoding scanlines.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Most images types will be kTopDown and will not need to override this function.
|
||||
*/
|
||||
virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
|
||||
|
||||
/**
|
||||
* Update the next scanline. Used by interlaced png.
|
||||
*/
|
||||
void updateNextScanline(int newY) { fCurrScanline = newY; }
|
||||
|
||||
const SkImageInfo& dstInfo() const { return fDstInfo; }
|
||||
|
||||
const SkCodec::Options& options() const { return fOptions; }
|
||||
|
||||
virtual int onOutputScanline(int inputScanline) const;
|
||||
|
||||
private:
|
||||
const SkImageInfo fSrcInfo;
|
||||
SkAutoTDelete<SkStream> fStream;
|
||||
bool fNeedsRewind;
|
||||
// These fields are only meaningful during scanline decodes.
|
||||
SkImageInfo fDstInfo;
|
||||
SkCodec::Options fOptions;
|
||||
int fCurrScanline;
|
||||
|
||||
/**
|
||||
* Return whether these dimensions are supported as a scale.
|
||||
*
|
||||
* The codec may choose to cache the information about scale and subset.
|
||||
* Either way, the same information will be passed to onGetPixels/onStart
|
||||
* on success.
|
||||
*
|
||||
* This must return true for a size returned from getScaledDimensions.
|
||||
*/
|
||||
bool dimensionsSupported(const SkISize& dim) {
|
||||
return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim);
|
||||
}
|
||||
|
||||
// Methods for scanline decoding.
|
||||
virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
|
||||
const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*ctableCount*/) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
// Naive default version just calls onGetScanlines on temp memory.
|
||||
virtual bool onSkipScanlines(int countLines) {
|
||||
// FIXME (msarett): Make this a pure virtual and always override this.
|
||||
SkAutoMalloc storage(fDstInfo.minRowBytes());
|
||||
|
||||
// Note that we pass 0 to rowBytes so we continue to use the same memory.
|
||||
// Also note that while getScanlines checks that rowBytes is big enough,
|
||||
// onGetScanlines bypasses that check.
|
||||
// Calling the virtual method also means we do not double count
|
||||
// countLines.
|
||||
return countLines == this->onGetScanlines(storage.get(), countLines, 0);
|
||||
}
|
||||
|
||||
virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
|
||||
|
||||
/**
|
||||
* On an incomplete decode, getPixels() and getScanlines() will call this function
|
||||
* to fill any uinitialized memory.
|
||||
*
|
||||
* @param dstInfo Contains the destination color type
|
||||
* Contains the destination alpha type
|
||||
* Contains the destination width
|
||||
* The height stored in this info is unused
|
||||
* @param dst Pointer to the start of destination pixel memory
|
||||
* @param rowBytes Stride length in destination pixel memory
|
||||
* @param zeroInit Indicates if memory is zero initialized
|
||||
* @param linesRequested Number of lines that the client requested
|
||||
* @param linesDecoded Number of lines that were successfully decoded
|
||||
*/
|
||||
void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
|
||||
|
||||
/**
|
||||
* Return an object which will allow forcing scanline decodes to sample in X.
|
||||
*
|
||||
* May create a sampler, if one is not currently being used. Otherwise, does
|
||||
* not affect ownership.
|
||||
*
|
||||
* Only valid during scanline decoding.
|
||||
*/
|
||||
virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
|
||||
|
||||
friend class SkSampledCodec;
|
||||
};
|
||||
#endif // SkCodec_DEFINED
|
27
gfx/skia/skia/include/codec/SkEncodedFormat.h
Normal file
27
gfx/skia/skia/include/codec/SkEncodedFormat.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkEncodedFormat_DEFINED
|
||||
#define SkEncodedFormat_DEFINED
|
||||
|
||||
/**
|
||||
* Enum describing format of encoded data.
|
||||
*/
|
||||
enum SkEncodedFormat {
|
||||
kUnknown_SkEncodedFormat,
|
||||
kBMP_SkEncodedFormat,
|
||||
kGIF_SkEncodedFormat,
|
||||
kICO_SkEncodedFormat,
|
||||
kJPEG_SkEncodedFormat,
|
||||
kPNG_SkEncodedFormat,
|
||||
kWBMP_SkEncodedFormat,
|
||||
kWEBP_SkEncodedFormat,
|
||||
kPKM_SkEncodedFormat,
|
||||
kKTX_SkEncodedFormat,
|
||||
kASTC_SkEncodedFormat,
|
||||
};
|
||||
#endif // SkEncodedFormat_DEFINED
|
@ -58,13 +58,6 @@
|
||||
//#define SK_DEBUG_GLYPH_CACHE
|
||||
//#define SK_DEBUG_PATH
|
||||
|
||||
/* To assist debugging, Skia provides an instance counting utility in
|
||||
include/core/SkInstCount.h. This flag turns on and off that utility to
|
||||
allow instance count tracking in either debug or release builds. By
|
||||
default it is enabled in debug but disabled in release.
|
||||
*/
|
||||
#define SK_ENABLE_INST_COUNT 0
|
||||
|
||||
/* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger)
|
||||
it will call SK_CRASH(). If this is not defined it, it is defined in
|
||||
SkPostConfig.h to write to an illegal address
|
||||
@ -107,14 +100,6 @@
|
||||
*/
|
||||
//#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024)
|
||||
|
||||
/* If zlib is available and you want to support the flate compression
|
||||
algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the
|
||||
include path. Alternatively, define SK_SYSTEM_ZLIB to use the system zlib
|
||||
library specified as "#include <zlib.h>".
|
||||
*/
|
||||
//#define SK_ZLIB_INCLUDE <zlib.h>
|
||||
//#define SK_SYSTEM_ZLIB
|
||||
|
||||
/* Define this to allow PDF scalars above 32k. The PDF/A spec doesn't allow
|
||||
them, but modern PDF interpreters should handle them just fine.
|
||||
*/
|
||||
@ -139,17 +124,15 @@
|
||||
//#define SK_SUPPORT_UNITTEST
|
||||
#endif
|
||||
|
||||
/* If your system embeds skia and has complex event logging, define this
|
||||
symbol to name a file that maps the following macros to your system's
|
||||
equivalents:
|
||||
SK_TRACE_EVENT0(event)
|
||||
SK_TRACE_EVENT1(event, name1, value1)
|
||||
SK_TRACE_EVENT2(event, name1, value1, name2, value2)
|
||||
src/utils/SkDebugTrace.h has a trivial implementation that writes to
|
||||
the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined,
|
||||
SkTrace.h will define the above three macros to do nothing.
|
||||
*/
|
||||
//#undef SK_USER_TRACE_INCLUDE_FILE
|
||||
/* Change the ordering to work in X windows.
|
||||
*/
|
||||
//#ifdef SK_SAMPLES_FOR_X
|
||||
// #define SK_R32_SHIFT 16
|
||||
// #define SK_G32_SHIFT 8
|
||||
// #define SK_B32_SHIFT 0
|
||||
// #define SK_A32_SHIFT 24
|
||||
//#endif
|
||||
|
||||
|
||||
/* Determines whether to build code that supports the GPU backend. Some classes
|
||||
that are not GPU-specific, such as SkShader subclasses, have optional code
|
||||
@ -161,40 +144,14 @@
|
||||
//#define SK_SUPPORT_GPU 1
|
||||
|
||||
|
||||
/* The PDF generation code uses Path Ops to generate inverse fills and complex
|
||||
* clipping paths, but at this time, Path Ops is not release ready yet. So,
|
||||
* the code is hidden behind this #define guard. If you are feeling adventurous
|
||||
* and want the latest and greatest PDF generation code, uncomment the #define.
|
||||
/* The PDF generation code uses Path Ops to handle complex clipping paths,
|
||||
* but at this time, Path Ops is not release ready yet. So, the code is
|
||||
* hidden behind this #define guard. If you are feeling adventurous and
|
||||
* want the latest and greatest PDF generation code, uncomment the #define.
|
||||
* When Path Ops is release ready, the define guards and this user config
|
||||
* define should be removed entirely.
|
||||
*/
|
||||
//#define SK_PDF_USE_PATHOPS
|
||||
|
||||
/* Skia uses these defines as the target of include preprocessor directives.
|
||||
* The header files pointed to by these defines provide declarations and
|
||||
* possibly inline implementations of threading primitives.
|
||||
*
|
||||
* See SkThread.h for documentation on what these includes must contain.
|
||||
*/
|
||||
//#define SK_ATOMICS_PLATFORM_H "SkAtomics_xxx.h"
|
||||
//#define SK_MUTEX_PLATFORM_H "SkMutex_xxx.h"
|
||||
#if defined(_MSC_VER)
|
||||
# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h"
|
||||
#else
|
||||
# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h"
|
||||
#else
|
||||
# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h"
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
|
||||
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h"
|
||||
#else
|
||||
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h"
|
||||
#endif
|
||||
//#define SK_PDF_USE_PATHOPS_CLIPPING
|
||||
|
||||
// On all platforms we have this byte order
|
||||
#define SK_A32_SHIFT 24
|
||||
@ -205,8 +162,21 @@
|
||||
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0
|
||||
|
||||
#define SK_SUPPORT_LEGACY_GETDEVICE
|
||||
|
||||
#define SK_IGNORE_ETC1_SUPPORT
|
||||
|
||||
#define SK_RASTERIZE_EVEN_ROUNDING
|
||||
|
||||
#define GR_GL_PER_GL_FUNC_CALLBACK 1
|
||||
|
||||
#define MOZ_SKIA 1
|
||||
|
||||
#ifndef MOZ_IMPLICIT
|
||||
# ifdef MOZ_CLANG_PLUGIN
|
||||
# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
|
||||
# else
|
||||
# define MOZ_IMPLICIT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -10,12 +10,11 @@
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkData;
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
struct SkPoint;
|
||||
|
||||
/**
|
||||
@ -27,12 +26,10 @@ public:
|
||||
virtual ~SkAnnotation();
|
||||
|
||||
static SkAnnotation* Create(const char key[], SkData* value) {
|
||||
return SkNEW_ARGS(SkAnnotation, (key, value));
|
||||
return new SkAnnotation(key, value);
|
||||
}
|
||||
|
||||
static SkAnnotation* Create(SkReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkAnnotation, (buffer));
|
||||
}
|
||||
static SkAnnotation* Create(SkReadBuffer& buffer) { return new SkAnnotation(buffer); }
|
||||
|
||||
/**
|
||||
* Return the data for the specified key, or NULL.
|
||||
|
@ -8,62 +8,24 @@
|
||||
#ifndef SkBBHFactory_DEFINED
|
||||
#define SkBBHFactory_DEFINED
|
||||
|
||||
#include "SkSize.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
#include "SkTypes.h"
|
||||
class SkBBoxHierarchy;
|
||||
struct SkRect;
|
||||
|
||||
class SK_API SkBBHFactory {
|
||||
public:
|
||||
/**
|
||||
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
|
||||
*/
|
||||
virtual SkBBoxHierarchy* operator()(int width, int height) const = 0;
|
||||
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0;
|
||||
virtual ~SkBBHFactory() {};
|
||||
};
|
||||
|
||||
class SK_API SkQuadTreeFactory : public SkBBHFactory {
|
||||
public:
|
||||
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
|
||||
private:
|
||||
typedef SkBBHFactory INHERITED;
|
||||
};
|
||||
|
||||
|
||||
class SK_API SkRTreeFactory : public SkBBHFactory {
|
||||
public:
|
||||
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
|
||||
SkBBoxHierarchy* operator()(const SkRect& bounds) const override;
|
||||
private:
|
||||
typedef SkBBHFactory INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkTileGridFactory : public SkBBHFactory {
|
||||
public:
|
||||
struct TileGridInfo {
|
||||
/** Tile placement interval */
|
||||
SkISize fTileInterval;
|
||||
|
||||
/** Pixel coverage overlap between adjacent tiles */
|
||||
SkISize fMargin;
|
||||
|
||||
/** Offset added to device-space bounding box positions to convert
|
||||
* them to tile-grid space. This can be used to adjust the "phase"
|
||||
* of the tile grid to match probable query rectangles that will be
|
||||
* used to search into the tile grid. As long as the offset is smaller
|
||||
* or equal to the margin, there is no need to extend the domain of
|
||||
* the tile grid to prevent data loss.
|
||||
*/
|
||||
SkIPoint fOffset;
|
||||
};
|
||||
|
||||
SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { }
|
||||
|
||||
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
TileGridInfo fInfo;
|
||||
|
||||
typedef SkBBHFactory INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SkColor.h"
|
||||
#include "SkColorTable.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkPixmap.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
@ -38,29 +39,6 @@ class SK_API SkBitmap {
|
||||
public:
|
||||
class SK_API Allocator;
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
|
||||
enum Config {
|
||||
kNo_Config, //!< bitmap has not been configured
|
||||
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
|
||||
kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
|
||||
kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
|
||||
};
|
||||
|
||||
// do not add this to the Config enum, otherwise the compiler will let us
|
||||
// pass this as a valid parameter for Config.
|
||||
enum {
|
||||
kConfigCount = kARGB_8888_Config + 1
|
||||
};
|
||||
|
||||
/** Return the config for the bitmap. */
|
||||
Config config() const;
|
||||
|
||||
SK_ATTR_DEPRECATED("use config()")
|
||||
Config getConfig() const { return this->config(); }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default construct creates a bitmap with zero width and height, and no pixels.
|
||||
* Its colortype is set to kUnknown_SkColorType.
|
||||
@ -91,10 +69,11 @@ public:
|
||||
|
||||
const SkImageInfo& info() const { return fInfo; }
|
||||
|
||||
int width() const { return fInfo.fWidth; }
|
||||
int height() const { return fInfo.fHeight; }
|
||||
SkColorType colorType() const { return fInfo.fColorType; }
|
||||
SkAlphaType alphaType() const { return fInfo.fAlphaType; }
|
||||
int width() const { return fInfo.width(); }
|
||||
int height() const { return fInfo.height(); }
|
||||
SkColorType colorType() const { return fInfo.colorType(); }
|
||||
SkAlphaType alphaType() const { return fInfo.alphaType(); }
|
||||
SkColorProfileType profileType() const { return fInfo.profileType(); }
|
||||
|
||||
/**
|
||||
* Return the number of bytes per pixel based on the colortype. If the colortype is
|
||||
@ -155,7 +134,7 @@ public:
|
||||
Note this truncates the result to 32bits. Call getSize64() to detect
|
||||
if the real size exceeds 32bits.
|
||||
*/
|
||||
size_t getSize() const { return fInfo.fHeight * fRowBytes; }
|
||||
size_t getSize() const { return fInfo.height() * fRowBytes; }
|
||||
|
||||
/** Return the number of bytes from the pointer returned by getPixels()
|
||||
to the end of the allocated space in the buffer. Required in
|
||||
@ -167,7 +146,7 @@ public:
|
||||
* Return the full size of the bitmap, in bytes.
|
||||
*/
|
||||
int64_t computeSize64() const {
|
||||
return sk_64_mul(fInfo.fHeight, fRowBytes);
|
||||
return sk_64_mul(fInfo.height(), fRowBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,6 +212,14 @@ public:
|
||||
void getBounds(SkRect* bounds) const;
|
||||
void getBounds(SkIRect* bounds) const;
|
||||
|
||||
SkIRect bounds() const { return fInfo.bounds(); }
|
||||
SkISize dimensions() const { return fInfo.dimensions(); }
|
||||
// Returns the bounds of this bitmap, offset by its pixelref origin.
|
||||
SkIRect getSubset() const {
|
||||
return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(),
|
||||
fInfo.width(), fInfo.height());
|
||||
}
|
||||
|
||||
bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
|
||||
|
||||
/**
|
||||
@ -241,7 +228,13 @@ public:
|
||||
* a colortable, then ColorTable must be non-null, and will be ref'd.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*/
|
||||
bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
|
||||
|
||||
void allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) {
|
||||
if (!this->tryAllocPixels(info, factory, ctable)) {
|
||||
sk_throw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the bitmap's pixels to match the requested image info and
|
||||
@ -251,24 +244,32 @@ public:
|
||||
* the pixel size specified by info.colorType()) then false is returned
|
||||
* and the bitmap is set to empty.
|
||||
*/
|
||||
bool allocPixels(const SkImageInfo& info, size_t rowBytes);
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Allocate a pixelref to match the specified image info, using the default
|
||||
* allocator.
|
||||
* On success, the bitmap's pixels will be "locked", and return true.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*/
|
||||
bool allocPixels(const SkImageInfo& info) {
|
||||
return this->allocPixels(info, info.minRowBytes());
|
||||
void allocPixels(const SkImageInfo& info, size_t rowBytes) {
|
||||
if (!this->tryAllocPixels(info, rowBytes)) {
|
||||
sk_throw();
|
||||
}
|
||||
}
|
||||
|
||||
bool allocN32Pixels(int width, int height, bool isOpaque = false) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
if (isOpaque) {
|
||||
info.fAlphaType = kOpaque_SkAlphaType;
|
||||
}
|
||||
return this->allocPixels(info);
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
|
||||
return this->tryAllocPixels(info, info.minRowBytes());
|
||||
}
|
||||
|
||||
void allocPixels(const SkImageInfo& info) {
|
||||
this->allocPixels(info, info.minRowBytes());
|
||||
}
|
||||
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32(width, height,
|
||||
isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
|
||||
return this->tryAllocPixels(info);
|
||||
}
|
||||
|
||||
void allocN32Pixels(int width, int height, bool isOpaque = false) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32(width, height,
|
||||
isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
|
||||
this->allocPixels(info);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,6 +278,9 @@ public:
|
||||
* referenced, if releaseProc is not null, it will be called with the
|
||||
* pixels and context as parameters.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*
|
||||
* If specified, the releaseProc will always be called, even on failure. It is also possible
|
||||
* for success but the releaseProc is immediately called (e.g. valid Info but NULL pixels).
|
||||
*/
|
||||
bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
|
||||
void (*releaseProc)(void* addr, void* context), void* context);
|
||||
@ -343,8 +347,12 @@ public:
|
||||
@return true if the allocation succeeds. If not the pixelref field of
|
||||
the bitmap will be unchanged.
|
||||
*/
|
||||
bool allocPixels(SkColorTable* ctable = NULL) {
|
||||
return this->allocPixels(NULL, ctable);
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) {
|
||||
return this->tryAllocPixels(NULL, ctable);
|
||||
}
|
||||
|
||||
void allocPixels(SkColorTable* ctable = NULL) {
|
||||
this->allocPixels(NULL, ctable);
|
||||
}
|
||||
|
||||
/** Use the specified Allocator to create the pixelref that manages the
|
||||
@ -365,7 +373,13 @@ public:
|
||||
@return true if the allocation succeeds. If not the pixelref field of
|
||||
the bitmap will be unchanged.
|
||||
*/
|
||||
bool allocPixels(Allocator* allocator, SkColorTable* ctable);
|
||||
bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable);
|
||||
|
||||
void allocPixels(Allocator* allocator, SkColorTable* ctable) {
|
||||
if (!this->tryAllocPixels(allocator, ctable)) {
|
||||
sk_throw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current pixelref object or NULL if there is none. This does
|
||||
@ -423,13 +437,15 @@ public:
|
||||
*/
|
||||
bool lockPixelsAreWritable() const;
|
||||
|
||||
bool requestLock(SkAutoPixmapUnlock* result) const;
|
||||
|
||||
/** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
|
||||
it has non-null pixels, and if required by its colortype, it has a
|
||||
non-null colortable. Returns true if all of the above are met.
|
||||
*/
|
||||
bool readyToDraw() const {
|
||||
return this->getPixels() != NULL &&
|
||||
(this->colorType() != kIndex_8_SkColorType || NULL != fColorTable);
|
||||
(this->colorType() != kIndex_8_SkColorType || fColorTable);
|
||||
}
|
||||
|
||||
/** Returns the pixelRef's texture, or NULL
|
||||
@ -462,10 +478,7 @@ public:
|
||||
* of the color is ignored (treated as opaque). If the colortype only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
void eraseColor(SkColor c) const {
|
||||
this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
|
||||
SkColorGetB(c));
|
||||
}
|
||||
void eraseColor(SkColor c) const;
|
||||
|
||||
/**
|
||||
* Fill the entire bitmap with the specified color.
|
||||
@ -473,7 +486,9 @@ public:
|
||||
* of the color is ignored (treated as opaque). If the colortype only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
|
||||
this->eraseColor(SkColorSetARGB(a, r, g, b));
|
||||
}
|
||||
|
||||
SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
|
||||
void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
|
||||
@ -486,29 +501,12 @@ public:
|
||||
* of the color is ignored (treated as opaque). If the colortype only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
void eraseArea(const SkIRect& area, SkColor c) const;
|
||||
void erase(SkColor c, const SkIRect& area) const;
|
||||
|
||||
/** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
|
||||
no pixels allocated (i.e. getPixels() returns null) the method will
|
||||
still update the inval region (if present). If the bitmap is immutable,
|
||||
do nothing and return false.
|
||||
|
||||
@param subset The subset of the bitmap to scroll/move. To scroll the
|
||||
entire contents, specify [0, 0, width, height] or just
|
||||
pass null.
|
||||
@param dx The amount to scroll in X
|
||||
@param dy The amount to scroll in Y
|
||||
@param inval Optional (may be null). Returns the area of the bitmap that
|
||||
was scrolled away. E.g. if dx = dy = 0, then inval would
|
||||
be set to empty. If dx >= width or dy >= height, then
|
||||
inval would be set to the entire bounds of the bitmap.
|
||||
@return true if the scroll was doable. Will return false if the colortype is kUnkown or
|
||||
if the bitmap is immutable.
|
||||
If no pixels are present (i.e. getPixels() returns false)
|
||||
inval will still be updated, and true will be returned.
|
||||
*/
|
||||
bool scrollRect(const SkIRect* subset, int dx, int dy,
|
||||
SkRegion* inval = NULL) const;
|
||||
// DEPRECATED
|
||||
void eraseArea(const SkIRect& area, SkColor c) const {
|
||||
this->erase(c, area);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SkColor of the specified pixel. In most cases this will
|
||||
@ -665,12 +663,21 @@ public:
|
||||
bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
/**
|
||||
* If the pixels are available from this bitmap (w/o locking) return true, and fill out the
|
||||
* specified pixmap (if not null). If the pixels are not available (either because there are
|
||||
* none, or becuase accessing them would require locking or other machinary) return false and
|
||||
* ignore the pixmap parameter.
|
||||
*
|
||||
* Note: if this returns true, the results (in the pixmap) are only valid until the bitmap
|
||||
* is changed in anyway, in which case the results are invalid.
|
||||
*/
|
||||
bool peekPixels(SkPixmap*) const;
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
class Allocator : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(Allocator)
|
||||
|
||||
/** Allocate the pixel memory for the bitmap, given its dimensions and
|
||||
colortype. Return true on success, where success means either setPixels
|
||||
or setPixelRef was called. The pixels need not be locked when this
|
||||
@ -689,7 +696,7 @@ public:
|
||||
*/
|
||||
class HeapAllocator : public Allocator {
|
||||
public:
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
|
||||
bool allocPixelRef(SkBitmap*, SkColorTable*) override;
|
||||
};
|
||||
|
||||
class RLEPixels {
|
||||
@ -736,24 +743,17 @@ private:
|
||||
};
|
||||
|
||||
SkImageInfo fInfo;
|
||||
|
||||
uint32_t fRowBytes;
|
||||
|
||||
uint8_t fFlags;
|
||||
|
||||
void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
|
||||
|
||||
/* Unreference any pixelrefs or colortables
|
||||
*/
|
||||
void freePixels();
|
||||
void updatePixelsFromRef() const;
|
||||
|
||||
void legacyUnflatten(SkReadBuffer&);
|
||||
|
||||
static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
|
||||
static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
|
||||
|
||||
friend class SkBitmapSource; // unflatten
|
||||
friend class SkReadBuffer; // unflatten, rawpixels
|
||||
friend class SkWriteBuffer; // rawpixels
|
||||
friend struct SkBitmapProcState;
|
||||
@ -780,60 +780,6 @@ private:
|
||||
//TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed.
|
||||
//#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels)
|
||||
|
||||
/** Helper class that performs the lock/unlockColors calls on a colortable.
|
||||
The destructor will call unlockColors(false) if it has a bitmap's colortable
|
||||
*/
|
||||
class SkAutoLockColors : SkNoncopyable {
|
||||
public:
|
||||
/** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
|
||||
colortable
|
||||
*/
|
||||
SkAutoLockColors() : fCTable(NULL), fColors(NULL) {}
|
||||
/** Initialize with bitmap, locking its colortable if present
|
||||
*/
|
||||
explicit SkAutoLockColors(const SkBitmap& bm) {
|
||||
fCTable = bm.getColorTable();
|
||||
fColors = fCTable ? fCTable->lockColors() : NULL;
|
||||
}
|
||||
/** Initialize with a colortable (may be null)
|
||||
*/
|
||||
explicit SkAutoLockColors(SkColorTable* ctable) {
|
||||
fCTable = ctable;
|
||||
fColors = ctable ? ctable->lockColors() : NULL;
|
||||
}
|
||||
~SkAutoLockColors() {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors();
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the currently locked colors, or NULL if no bitmap's colortable
|
||||
is currently locked.
|
||||
*/
|
||||
const SkPMColor* colors() const { return fColors; }
|
||||
|
||||
/** Locks the table and returns is colors (assuming ctable is not null) and
|
||||
unlocks the previous table if one was present
|
||||
*/
|
||||
const SkPMColor* lockColors(SkColorTable* ctable) {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors();
|
||||
}
|
||||
fCTable = ctable;
|
||||
fColors = ctable ? ctable->lockColors() : NULL;
|
||||
return fColors;
|
||||
}
|
||||
|
||||
const SkPMColor* lockColors(const SkBitmap& bm) {
|
||||
return this->lockColors(bm.getColorTable());
|
||||
}
|
||||
|
||||
private:
|
||||
SkColorTable* fCTable;
|
||||
const SkPMColor* fColors;
|
||||
};
|
||||
#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
|
||||
@ -865,13 +811,4 @@ inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
|
||||
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Helpers until we can fully deprecate SkBitmap::Config
|
||||
//
|
||||
SK_API SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
|
||||
SK_API SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -9,54 +9,74 @@
|
||||
#ifndef SkBitmapDevice_DEFINED
|
||||
#define SkBitmapDevice_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkScalar.h"
|
||||
#include "SkSize.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkDraw;
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
class SkPixelRef;
|
||||
class SkPixmap;
|
||||
class SkRRect;
|
||||
class SkSurface;
|
||||
class SkXfermode;
|
||||
struct SkPoint;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class SK_API SkBitmapDevice : public SkBaseDevice {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBitmapDevice)
|
||||
|
||||
/**
|
||||
* Construct a new device with the specified bitmap as its backend. It is
|
||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||
* any drawing to this device will have no effect.
|
||||
*/
|
||||
*/
|
||||
SkBitmapDevice(const SkBitmap& bitmap);
|
||||
|
||||
/**
|
||||
* Create a new device along with its requisite pixel memory using
|
||||
* default SkSurfaceProps (i.e., kLegacyFontHost_InitType-style).
|
||||
* Note: this entry point is slated for removal - no one should call it.
|
||||
*/
|
||||
static SkBitmapDevice* Create(const SkImageInfo& info);
|
||||
|
||||
/**
|
||||
* Construct a new device with the specified bitmap as its backend. It is
|
||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||
* any drawing to this device will have no effect.
|
||||
*/
|
||||
SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
|
||||
*/
|
||||
SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps);
|
||||
|
||||
static SkBitmapDevice* Create(const SkImageInfo&,
|
||||
const SkDeviceProperties* = NULL);
|
||||
static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&);
|
||||
|
||||
virtual SkImageInfo imageInfo() const SK_OVERRIDE;
|
||||
SkImageInfo imageInfo() const override;
|
||||
|
||||
protected:
|
||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE;
|
||||
|
||||
/** Clears the entire device to the specified color (including alpha).
|
||||
* Ignores the clip.
|
||||
*/
|
||||
virtual void clear(SkColor color) SK_OVERRIDE;
|
||||
bool onShouldDisableLCD(const SkPaint&) const override;
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkPoint[], const SkPaint& paint) override;
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkPaint& paint) override;
|
||||
virtual void drawOval(const SkDraw&, const SkRect& oval,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkPaint& paint) override;
|
||||
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkPaint& paint) override;
|
||||
|
||||
/**
|
||||
* If pathIsMutable, then the implementation is allowed to cast path to a
|
||||
@ -72,43 +92,34 @@ protected:
|
||||
virtual void drawPath(const SkDraw&, const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = NULL,
|
||||
bool pathIsMutable = false) SK_OVERRIDE;
|
||||
bool pathIsMutable = false) override;
|
||||
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkMatrix& matrix, const SkPaint& paint) override;
|
||||
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) SK_OVERRIDE;
|
||||
int x, int y, const SkPaint& paint) override;
|
||||
|
||||
/**
|
||||
* The default impl. will create a bitmap-shader from the bitmap,
|
||||
* and call drawRect with it.
|
||||
*/
|
||||
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
* Decorations (underline and stike-thru) will be handled by SkCanvas.
|
||||
*/
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE;
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) override;
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE;
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) override;
|
||||
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
/** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to
|
||||
onCreateDevice on this device with kSaveLayer_Usage.
|
||||
*/
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) SK_OVERRIDE;
|
||||
const SkPaint& paint) override;
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -117,7 +128,7 @@ protected:
|
||||
altered. The config/width/height/rowbytes must remain unchanged.
|
||||
@return the device contents as a bitmap
|
||||
*/
|
||||
virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
|
||||
const SkBitmap& onAccessBitmap() override;
|
||||
|
||||
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
|
||||
// just for subclasses, to assign a custom pixelref
|
||||
@ -126,15 +137,12 @@ protected:
|
||||
return pr;
|
||||
}
|
||||
|
||||
virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE;
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
|
||||
virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes) SK_OVERRIDE;
|
||||
|
||||
/** Called when this device is installed into a Canvas. Balanced by a call
|
||||
to unlockPixels() when the device is removed from a Canvas.
|
||||
*/
|
||||
virtual void lockPixels() SK_OVERRIDE;
|
||||
virtual void unlockPixels() SK_OVERRIDE;
|
||||
bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) override;
|
||||
bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override;
|
||||
bool onPeekPixels(SkPixmap*) override;
|
||||
bool onAccessPixels(SkPixmap*) override;
|
||||
void onAttachToCanvas(SkCanvas*) override;
|
||||
void onDetachFromCanvas() override;
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
@ -142,22 +150,24 @@ private:
|
||||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
friend class SkDeviceImageFilterProxy;
|
||||
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
// any clip information.
|
||||
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE;
|
||||
void replaceBitmapBackendForRasterSurface(const SkBitmap&) override;
|
||||
|
||||
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
|
||||
SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
|
||||
|
||||
virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
|
||||
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE;
|
||||
SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
||||
SkImageFilter::Cache* getImageFilterCache() override;
|
||||
|
||||
SkBitmap fBitmap;
|
||||
|
||||
void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture().
|
||||
|
||||
typedef SkBaseDevice INHERITED;
|
||||
};
|
||||
|
||||
|
@ -26,17 +26,26 @@ public:
|
||||
a corresponding scanline of 16bit colors (specific format based on the
|
||||
config passed to the Factory.
|
||||
|
||||
The x,y params are useful just for dithering
|
||||
The x,y params provide the dithering phase for the start of the scanline
|
||||
|
||||
@param alpha A global alpha to be applied to all of the src colors
|
||||
@param x The x coordinate of the beginning of the scanline
|
||||
@param y THe y coordinate of the scanline
|
||||
*/
|
||||
typedef void (*Proc)(uint16_t* dst,
|
||||
const SkPMColor* src,
|
||||
int count, U8CPU alpha, int x, int y);
|
||||
typedef void (*Proc16)(uint16_t dst[], const SkPMColor src[], int count,
|
||||
U8CPU alpha, int x, int y);
|
||||
|
||||
static Proc Factory(unsigned flags, SkColorType);
|
||||
static Proc16 Factory16(unsigned flags);
|
||||
|
||||
/**
|
||||
* Function pointer that blends a single src color onto a scaline of dst colors.
|
||||
*
|
||||
* The x,y params provide the dithering phase for the start of the scanline
|
||||
*/
|
||||
typedef void (*ColorProc16)(uint16_t dst[], SkPMColor src, int count, int x, int y);
|
||||
|
||||
// Note : we ignore the kGlobalAlpha_Flag setting, but do respect kSrcPixelAlpha_Flag
|
||||
static ColorProc16 ColorFactory16(unsigned flags);
|
||||
|
||||
///////////// D32 version
|
||||
|
||||
@ -51,38 +60,15 @@ public:
|
||||
@param count number of colors to blend
|
||||
@param alpha global alpha to be applied to all src colors
|
||||
*/
|
||||
typedef void (*Proc32)(uint32_t* dst,
|
||||
const SkPMColor* src,
|
||||
int count, U8CPU alpha);
|
||||
typedef void (*Proc32)(uint32_t dst[], const SkPMColor src[], int count, U8CPU alpha);
|
||||
|
||||
static Proc32 Factory32(unsigned flags32);
|
||||
|
||||
/** Function pointer that blends a single color with a row of 32-bit colors
|
||||
onto a 32-bit destination
|
||||
*/
|
||||
typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count,
|
||||
SkPMColor color);
|
||||
|
||||
/** Blend a single color onto a row of S32 pixels, writing the result
|
||||
into a row of D32 pixels. src and dst may be the same memory, but
|
||||
if they are not, they may not overlap.
|
||||
*/
|
||||
static void Color32(SkPMColor dst[], const SkPMColor src[],
|
||||
int count, SkPMColor color);
|
||||
|
||||
//! Public entry-point to return a blit function ptr
|
||||
static ColorProc ColorProcFactory();
|
||||
|
||||
/** Function pointer that blends a single color onto a 32-bit rectangle. */
|
||||
typedef void (*ColorRectProc)(SkPMColor* dst, int width, int height,
|
||||
size_t rowBytes, SkPMColor color);
|
||||
|
||||
/** Blend a single color into a rectangle of D32 pixels. */
|
||||
static void ColorRect32(SkPMColor* dst, int width, int height,
|
||||
size_t rowBytes, SkPMColor color);
|
||||
|
||||
//! Public entry-point to return a blit function ptr
|
||||
static ColorRectProc ColorRectProcFactory();
|
||||
static void Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color);
|
||||
|
||||
/** These static functions are called by the Factory and Factory32
|
||||
functions, and should return either NULL, or a
|
||||
@ -91,8 +77,9 @@ public:
|
||||
*/
|
||||
|
||||
static Proc32 PlatformProcs32(unsigned flags);
|
||||
static Proc PlatformProcs565(unsigned flags);
|
||||
static ColorProc PlatformColorProc();
|
||||
|
||||
static Proc16 PlatformFactory565(unsigned flags);
|
||||
static ColorProc16 PlatformColorFactory565(unsigned flags);
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
@ -11,30 +11,31 @@
|
||||
#include "SkTypes.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkClipStack.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL
|
||||
#define SK_LEGACY_DRAWTEXT_VIRTUAL virtual
|
||||
#else
|
||||
#define SK_LEGACY_DRAWTEXT_VIRTUAL
|
||||
#endif
|
||||
|
||||
class SkCanvasClipVisitor;
|
||||
class SkBaseDevice;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkMetaData;
|
||||
class SkPicture;
|
||||
class SkRRect;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class GrContext;
|
||||
class GrRenderTarget;
|
||||
class SkBaseDevice;
|
||||
class SkCanvasClipVisitor;
|
||||
class SkClipStack;
|
||||
class SkDraw;
|
||||
class SkDrawable;
|
||||
class SkDrawFilter;
|
||||
class SkImage;
|
||||
class SkImageFilter;
|
||||
class SkMetaData;
|
||||
class SkPath;
|
||||
class SkPicture;
|
||||
class SkPixmap;
|
||||
class SkRRect;
|
||||
struct SkRSXform;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class SkTextBlob;
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
@ -53,37 +54,6 @@ class GrRenderTarget;
|
||||
*/
|
||||
class SK_API SkCanvas : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkCanvas)
|
||||
|
||||
/**
|
||||
* Attempt to allocate an offscreen raster canvas, matching the ImageInfo.
|
||||
* On success, return a new canvas that will draw into that offscreen.
|
||||
*
|
||||
* The caller can access the pixels after drawing into this canvas by
|
||||
* calling readPixels() or peekPixels().
|
||||
*
|
||||
* If the requested ImageInfo is opaque (either the colortype is
|
||||
* intrinsically opaque like RGB_565, or the info's alphatype is kOpaque)
|
||||
* then the pixel memory may be uninitialized. Otherwise, the pixel memory
|
||||
* will be initialized to 0, which is interpreted as transparent.
|
||||
*
|
||||
* On failure, return NULL. This can fail for several reasons:
|
||||
* 1. the memory allocation failed (e.g. request is too large)
|
||||
* 2. invalid ImageInfo (e.g. negative dimensions)
|
||||
* 3. unsupported ImageInfo for a canvas
|
||||
* - kUnknown_SkColorType, kIndex_8_SkColorType
|
||||
* - kIgnore_SkAlphaType
|
||||
* - this list is not complete, so others may also be unsupported
|
||||
*
|
||||
* Note: it is valid to request a supported ImageInfo, but with zero
|
||||
* dimensions.
|
||||
*/
|
||||
static SkCanvas* NewRaster(const SkImageInfo&);
|
||||
|
||||
static SkCanvas* NewRasterN32(int width, int height) {
|
||||
return NewRaster(SkImageInfo::MakeN32Premul(width, height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
|
||||
* specified pixels. To access the pixels after drawing to them, the caller should call
|
||||
@ -93,7 +63,7 @@ public:
|
||||
* 1. invalid ImageInfo (e.g. negative dimensions)
|
||||
* 2. unsupported ImageInfo for a canvas
|
||||
* - kUnknown_SkColorType, kIndex_8_SkColorType
|
||||
* - kIgnore_SkAlphaType
|
||||
* - kUnknown_SkAlphaType
|
||||
* - this list is not complete, so others may also be unsupported
|
||||
*
|
||||
* Note: it is valid to request a supported ImageInfo, but with zero
|
||||
@ -116,7 +86,7 @@ public:
|
||||
* by any device/pixels. Typically this use used by subclasses who handle
|
||||
* the draw calls in some other way.
|
||||
*/
|
||||
SkCanvas(int width, int height);
|
||||
SkCanvas(int width, int height, const SkSurfaceProps* = NULL);
|
||||
|
||||
/** Construct a canvas with the specified device to draw into.
|
||||
|
||||
@ -129,6 +99,14 @@ public:
|
||||
structure are copied to the canvas.
|
||||
*/
|
||||
explicit SkCanvas(const SkBitmap& bitmap);
|
||||
|
||||
/** Construct a canvas with the specified bitmap to draw into.
|
||||
@param bitmap Specifies a bitmap for the canvas to draw into. Its
|
||||
structure are copied to the canvas.
|
||||
@param props New canvas surface properties.
|
||||
*/
|
||||
SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
|
||||
|
||||
virtual ~SkCanvas();
|
||||
|
||||
SkMetaData& getMetaData();
|
||||
@ -151,7 +129,7 @@ public:
|
||||
* origin of the base layer is always (0,0). The current drawable area may be
|
||||
* smaller (due to clipping or saveLayer).
|
||||
*/
|
||||
SkISize getBaseLayerSize() const;
|
||||
virtual SkISize getBaseLayerSize() const;
|
||||
|
||||
/**
|
||||
* DEPRECATED: call getBaseLayerSize
|
||||
@ -169,6 +147,9 @@ protected: // Can we make this private?
|
||||
#endif
|
||||
SkBaseDevice* getDevice() const;
|
||||
public:
|
||||
SkBaseDevice* getDevice_just_for_deprecated_compatibility_testing() const {
|
||||
return this->getDevice();
|
||||
}
|
||||
|
||||
/**
|
||||
* saveLayer() can create another device (which is later drawn onto
|
||||
@ -193,8 +174,12 @@ public:
|
||||
* Create a new surface matching the specified info, one that attempts to
|
||||
* be maximally compatible when used with this canvas. If there is no matching Surface type,
|
||||
* NULL is returned.
|
||||
*
|
||||
* If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
|
||||
* inherits the properties of the surface that owns this canvas. If this canvas has no parent
|
||||
* surface, then the new surface is created with default properties.
|
||||
*/
|
||||
SkSurface* newSurface(const SkImageInfo&);
|
||||
SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL);
|
||||
|
||||
/**
|
||||
* Return the GPU context of the device that is associated with the canvas.
|
||||
@ -347,6 +332,9 @@ public:
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
int saveLayer(const SkRect* bounds, const SkPaint* paint);
|
||||
int saveLayer(const SkRect& bounds, const SkPaint* paint) {
|
||||
return this->saveLayer(&bounds, paint);
|
||||
}
|
||||
|
||||
/** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead.
|
||||
|
||||
@ -417,11 +405,6 @@ public:
|
||||
*/
|
||||
void restoreToCount(int saveCount);
|
||||
|
||||
/** Returns true if drawing is currently going to a layer (from saveLayer)
|
||||
* rather than to the root device.
|
||||
*/
|
||||
virtual bool isDrawingToLayer() const;
|
||||
|
||||
/** Preconcat the current matrix with the specified translation
|
||||
@param dx The distance to translate in X
|
||||
@param dy The distance to translate in Y
|
||||
@ -609,24 +592,15 @@ public:
|
||||
@param color the color to draw with
|
||||
@param mode the mode to apply the color in (defaults to SrcOver)
|
||||
*/
|
||||
void drawColor(SkColor color,
|
||||
SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
|
||||
void drawColor(SkColor color, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
|
||||
|
||||
/**
|
||||
* This erases the entire drawing surface to the specified color,
|
||||
* irrespective of the clip. It does not blend with the previous pixels,
|
||||
* but always overwrites them.
|
||||
*
|
||||
* It is roughly equivalent to the following:
|
||||
* canvas.save();
|
||||
* canvas.clipRect(hugeRect, kReplace_Op);
|
||||
* paint.setColor(color);
|
||||
* paint.setXfermodeMode(kSrc_Mode);
|
||||
* canvas.drawPaint(paint);
|
||||
* canvas.restore();
|
||||
* though it is almost always much more efficient.
|
||||
* Helper method for drawing a color in SRC mode, completely replacing all the pixels
|
||||
* in the current clip with this color.
|
||||
*/
|
||||
virtual void clear(SkColor);
|
||||
void clear(SkColor color) {
|
||||
this->drawColor(color, SkXfermode::kSrc_Mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes the contents of the canvas undefined. Subsequent calls that
|
||||
@ -647,7 +621,7 @@ public:
|
||||
* specified paint.
|
||||
* @param paint The paint used to fill the canvas
|
||||
*/
|
||||
virtual void drawPaint(const SkPaint& paint);
|
||||
void drawPaint(const SkPaint& paint);
|
||||
|
||||
enum PointMode {
|
||||
/** drawPoints draws each point separately */
|
||||
@ -679,8 +653,7 @@ public:
|
||||
@param pts Array of points to draw
|
||||
@param paint The paint used to draw the points
|
||||
*/
|
||||
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
||||
const SkPaint& paint);
|
||||
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
|
||||
|
||||
/** Helper method for drawing a single point. See drawPoints() for a more
|
||||
details.
|
||||
@ -711,7 +684,7 @@ public:
|
||||
@param rect The rect to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
virtual void drawRect(const SkRect& rect, const SkPaint& paint);
|
||||
void drawRect(const SkRect& rect, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified rectangle using the specified paint. The rectangle
|
||||
will be filled or framed based on the Style in the paint.
|
||||
@ -740,7 +713,7 @@ public:
|
||||
@param oval The rectangle bounds of the oval to be drawn
|
||||
@param paint The paint used to draw the oval
|
||||
*/
|
||||
virtual void drawOval(const SkRect& oval, const SkPaint&);
|
||||
void drawOval(const SkRect& oval, const SkPaint&);
|
||||
|
||||
/**
|
||||
* Draw the specified RRect using the specified paint The rrect will be filled or stroked
|
||||
@ -749,7 +722,7 @@ public:
|
||||
* @param rrect The round-rect to draw
|
||||
* @param paint The paint used to draw the round-rect
|
||||
*/
|
||||
virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint);
|
||||
void drawRRect(const SkRRect& rrect, const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* Draw the annulus formed by the outer and inner rrects. The results
|
||||
@ -797,7 +770,84 @@ public:
|
||||
@param path The path to be drawn
|
||||
@param paint The paint used to draw the path
|
||||
*/
|
||||
virtual void drawPath(const SkPath& path, const SkPaint& paint);
|
||||
void drawPath(const SkPath& path, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified image, with its top/left corner at (x,y), using the
|
||||
specified paint, transformed by the current matrix.
|
||||
|
||||
@param image The image to be drawn
|
||||
@param left The position of the left side of the image being drawn
|
||||
@param top The position of the top side of the image being drawn
|
||||
@param paint The paint used to draw the image, or NULL
|
||||
*/
|
||||
void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL);
|
||||
|
||||
/**
|
||||
* Controls the behavior at the edge of the src-rect, when specified in drawImageRect,
|
||||
* trading off speed for exactness.
|
||||
*
|
||||
* When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around
|
||||
* the pixels in the image. If there is a src-rect specified, it is intended to restrict the
|
||||
* pixels that will be read. However, for performance reasons, some implementations may slow
|
||||
* down if they cannot read 1-pixel past the src-rect boundary at times.
|
||||
*
|
||||
* This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable.
|
||||
* If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect
|
||||
* must be strictly respected, the caller should pass kStrict.
|
||||
*/
|
||||
enum SrcRectConstraint {
|
||||
/**
|
||||
* If kStrict is specified, the implementation must respect the src-rect
|
||||
* (if specified) strictly, and will never sample outside of those bounds during sampling
|
||||
* even when filtering. This may be slower than kFast.
|
||||
*/
|
||||
kStrict_SrcRectConstraint,
|
||||
|
||||
/**
|
||||
* If kFast is specified, the implementation may sample outside of the src-rect
|
||||
* (if specified) by half the width of filter. This allows greater flexibility
|
||||
* to the implementation and can make the draw much faster.
|
||||
*/
|
||||
kFast_SrcRectConstraint,
|
||||
};
|
||||
|
||||
/** Draw the specified image, scaling and translating so that it fills the specified
|
||||
* dst rect. If the src rect is non-null, only that subset of the image is transformed
|
||||
* and drawn.
|
||||
*
|
||||
* @param image The image to be drawn
|
||||
* @param src Optional: specify the subset of the image to be drawn
|
||||
* @param dst The destination rectangle where the scaled/translated
|
||||
* image will be drawn
|
||||
* @param paint The paint used to draw the image, or NULL
|
||||
* @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
|
||||
*/
|
||||
void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
|
||||
const SkPaint* paint,
|
||||
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
|
||||
// variant that takes src SkIRect
|
||||
void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
|
||||
const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
// variant that assumes src == image-bounds
|
||||
void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
|
||||
SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
|
||||
/**
|
||||
* Draw the image stretched differentially to fit into dst.
|
||||
* center is a rect within the image, and logically divides the image
|
||||
* into 9 sections (3x3). For example, if the middle pixel of a [5x5]
|
||||
* image is the "center", then the center-rect should be [2, 2, 3, 3].
|
||||
*
|
||||
* If the dst is >= the image size, then...
|
||||
* - The 4 corners are not stretched at all.
|
||||
* - The sides are stretched in only one axis.
|
||||
* - The center is stretched in both axes.
|
||||
* Else, for each axis where dst < image,
|
||||
* - The corners shrink proportionally
|
||||
* - The sides (along the shrink axis) and center are not drawn
|
||||
*/
|
||||
void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y), using the
|
||||
specified paint, transformed by the current matrix. Note: if the paint
|
||||
@ -815,51 +865,27 @@ public:
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
|
||||
const SkPaint* paint = NULL);
|
||||
void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
enum DrawBitmapRectFlags {
|
||||
kNone_DrawBitmapRectFlag = 0x0,
|
||||
/**
|
||||
* When filtering is enabled, allow the color samples outside of
|
||||
* the src rect (but still in the src bitmap) to bleed into the
|
||||
* drawn portion
|
||||
*/
|
||||
kBleed_DrawBitmapRectFlag = 0x1,
|
||||
};
|
||||
|
||||
/** Draw the specified bitmap, with the specified matrix applied (before the
|
||||
canvas' matrix is applied).
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param src Optional: specify the subset of the bitmap to be drawn
|
||||
@param dst The destination rectangle where the scaled/translated
|
||||
image will be drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint = NULL,
|
||||
DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag);
|
||||
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
|
||||
const SkPaint* paint = NULL) {
|
||||
this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
|
||||
}
|
||||
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc,
|
||||
const SkRect& dst, const SkPaint* paint = NULL,
|
||||
DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) {
|
||||
SkRect realSrcStorage;
|
||||
SkRect* realSrcPtr = NULL;
|
||||
if (isrc) {
|
||||
realSrcStorage.set(*isrc);
|
||||
realSrcPtr = &realSrcStorage;
|
||||
}
|
||||
this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags);
|
||||
}
|
||||
|
||||
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
|
||||
const SkPaint* paint = NULL);
|
||||
/** Draw the specified bitmap, scaling and translating so that it fills the specified
|
||||
* dst rect. If the src rect is non-null, only that subset of the bitmap is transformed
|
||||
* and drawn.
|
||||
*
|
||||
* @param bitmap The bitmap to be drawn
|
||||
* @param src Optional: specify the subset of the bitmap to be drawn
|
||||
* @param dst The destination rectangle where the scaled/translated
|
||||
* bitmap will be drawn
|
||||
* @param paint The paint used to draw the bitmap, or NULL
|
||||
* @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
|
||||
*/
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
|
||||
const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
// variant where src is SkIRect
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
|
||||
const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
|
||||
SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
|
||||
/**
|
||||
* Draw the bitmap stretched differentially to fit into dst.
|
||||
@ -875,8 +901,8 @@ public:
|
||||
* - The corners shrink proportionally
|
||||
* - The sides (along the shrink axis) and center are not drawn
|
||||
*/
|
||||
virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint* paint = NULL);
|
||||
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y),
|
||||
NOT transformed by the current matrix. Note: if the paint
|
||||
@ -889,8 +915,7 @@ public:
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
|
||||
const SkPaint* paint = NULL);
|
||||
void drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint.
|
||||
The origin is interpreted based on the Align setting in the paint.
|
||||
@ -900,8 +925,8 @@ public:
|
||||
@param y The y-coordinate of the origin of the text being drawn
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
SK_LEGACY_DRAWTEXT_VIRTUAL void drawText(const void* text, size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint& paint);
|
||||
void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with each character/glyph origin specified by the pos[]
|
||||
array. The origin is interpreted by the Align setting in the paint.
|
||||
@ -910,8 +935,8 @@ public:
|
||||
@param pos Array of positions, used to position each character
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosText(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint);
|
||||
void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with each character/glyph origin specified by the x
|
||||
coordinate taken from the xpos[] array, and the y from the constY param.
|
||||
@ -922,9 +947,8 @@ public:
|
||||
@param constY The shared Y coordinate for all of the positions
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint);
|
||||
void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint, along
|
||||
the specified path. The paint's Align setting determins where along the
|
||||
@ -938,8 +962,7 @@ public:
|
||||
position the text
|
||||
@param paint The paint used for the text
|
||||
*/
|
||||
void drawTextOnPathHV(const void* text, size_t byteLength,
|
||||
const SkPath& path, SkScalar hOffset,
|
||||
void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
|
||||
SkScalar vOffset, const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint, along
|
||||
@ -952,17 +975,16 @@ public:
|
||||
mapped onto the path
|
||||
@param paint The paint used for the text
|
||||
*/
|
||||
SK_LEGACY_DRAWTEXT_VIRTUAL void drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
|
||||
const SkMatrix* matrix, const SkPaint& paint);
|
||||
|
||||
/** PRIVATE / EXPERIMENTAL -- do not call
|
||||
Perform back-end analysis/optimization of a picture. This may attach
|
||||
optimization data to the picture which can be used by a later
|
||||
drawPicture call.
|
||||
@param picture The recorded drawing commands to analyze/optimize
|
||||
/** Draw the text blob, offset by (x,y), using the specified paint.
|
||||
@param blob The text blob to be drawn
|
||||
@param x The x-offset of the text being drawn
|
||||
@param y The y-offset of the text being drawn
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void EXPERIMENTAL_optimize(const SkPicture* picture);
|
||||
void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
|
||||
/** Draw the picture into this canvas. This method effective brackets the
|
||||
playback of the picture's draw calls with save/restore, so the state
|
||||
@ -970,7 +992,23 @@ public:
|
||||
@param picture The recorded drawing commands to playback into this
|
||||
canvas.
|
||||
*/
|
||||
void drawPicture(const SkPicture* picture);
|
||||
void drawPicture(const SkPicture* picture) {
|
||||
this->drawPicture(picture, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the picture into this canvas.
|
||||
*
|
||||
* If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
|
||||
* logically equivalent to
|
||||
* save/concat/drawPicture/restore
|
||||
*
|
||||
* If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
|
||||
* alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
|
||||
* This is logically equivalent to
|
||||
* saveLayer(paint)/drawPicture/restore
|
||||
*/
|
||||
void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint);
|
||||
|
||||
enum VertexMode {
|
||||
kTriangles_VertexMode,
|
||||
@ -1001,48 +1039,64 @@ public:
|
||||
@param indexCount number of entries in the indices array (if not null)
|
||||
@param paint Specifies the shader/texture if present.
|
||||
*/
|
||||
virtual void drawVertices(VertexMode vmode, int vertexCount,
|
||||
const SkPoint vertices[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint);
|
||||
void drawVertices(VertexMode vmode, int vertexCount,
|
||||
const SkPoint vertices[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Send a blob of data to the canvas.
|
||||
For canvases that draw, this call is effectively a no-op, as the data
|
||||
is not parsed, but just ignored. However, this call exists for
|
||||
subclasses like SkPicture's recording canvas, that can store the data
|
||||
and then play it back later (via another call to drawData).
|
||||
*/
|
||||
virtual void drawData(const void* data, size_t length) {
|
||||
// do nothing. Subclasses may do something with the data
|
||||
}
|
||||
/**
|
||||
Draw a cubic coons patch
|
||||
|
||||
/** Add comments. beginCommentGroup/endCommentGroup open/close a new group.
|
||||
Each comment added via addComment is notionally attached to its
|
||||
enclosing group. Top-level comments simply belong to no group.
|
||||
@param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
|
||||
starting at the top left corner.
|
||||
@param colors specifies the colors for the corners which will be bilerp across the patch,
|
||||
their order is clockwise starting at the top left corner.
|
||||
@param texCoords specifies the texture coordinates that will be bilerp across the patch,
|
||||
their order is the same as the colors.
|
||||
@param xmode specifies how are the colors and the textures combined if both of them are
|
||||
present.
|
||||
@param paint Specifies the shader/texture if present.
|
||||
*/
|
||||
virtual void beginCommentGroup(const char* description) {
|
||||
// do nothing. Subclasses may do something
|
||||
}
|
||||
virtual void addComment(const char* kywd, const char* value) {
|
||||
// do nothing. Subclasses may do something
|
||||
}
|
||||
virtual void endCommentGroup() {
|
||||
// do nothing. Subclasses may do something
|
||||
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the
|
||||
* coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle
|
||||
* into a quad.
|
||||
*
|
||||
* xform maps [0, 0, tex.width, tex.height] -> quad
|
||||
*
|
||||
* The color array is optional. When specified, each color modulates the pixels in its
|
||||
* corresponding quad (via the specified SkXfermode::Mode).
|
||||
*
|
||||
* The cullRect is optional. When specified, it must be a conservative bounds of all of the
|
||||
* resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
|
||||
* intersect the current clip.
|
||||
*
|
||||
* The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
|
||||
* and xfermode are used to affect each of the quads.
|
||||
*/
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode, const SkRect* cullRect,
|
||||
const SkPaint* paint);
|
||||
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
|
||||
const SkRect* cullRect, const SkPaint* paint) {
|
||||
this->drawAtlas(atlas, xform, tex, NULL, count, SkXfermode::kDst_Mode, cullRect, paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* With this call the client asserts that subsequent draw operations (up to the
|
||||
* matching popCull()) are fully contained within the given bounding box. The assertion
|
||||
* is not enforced, but the information might be used to quick-reject command blocks,
|
||||
* so an incorrect bounding box may result in incomplete rendering.
|
||||
* Draw the contents of this drawable into the canvas. If the canvas is async
|
||||
* (e.g. it is recording into a picture) then the drawable will be referenced instead,
|
||||
* to have its draw() method called when the picture is finalized.
|
||||
*
|
||||
* If the intent is to force the contents of the drawable into this canvas immediately,
|
||||
* then drawable->draw(canvas) may be called.
|
||||
*/
|
||||
void pushCull(const SkRect& cullRect);
|
||||
|
||||
/**
|
||||
* Terminates the current culling block, and restores the previous one (if any).
|
||||
*/
|
||||
void popCull();
|
||||
void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL);
|
||||
void drawDrawable(SkDrawable*, SkScalar x, SkScalar y);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1085,25 +1139,13 @@ public:
|
||||
*/
|
||||
const SkMatrix& getTotalMatrix() const;
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
|
||||
enum ClipType {
|
||||
kEmpty_ClipType = 0,
|
||||
kRect_ClipType,
|
||||
kComplex_ClipType
|
||||
};
|
||||
/** Returns a description of the total clip; may be cheaper than
|
||||
getting the clip and querying it directly.
|
||||
*/
|
||||
virtual ClipType getClipType() const;
|
||||
#endif
|
||||
|
||||
/** Return the clip stack. The clip stack stores all the individual
|
||||
* clips organized by the save/restore frame in which they were
|
||||
* added.
|
||||
* @return the current clip stack ("list" of individual clip elements)
|
||||
*/
|
||||
const SkClipStack* getClipStack() const {
|
||||
return &fClipStack;
|
||||
return fClipStack;
|
||||
}
|
||||
|
||||
typedef SkCanvasClipVisitor ClipVisitor;
|
||||
@ -1154,20 +1196,30 @@ public:
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
// don't call
|
||||
const SkRegion& internal_private_getTotalClip() const;
|
||||
// don't call
|
||||
void internal_private_getTotalClipAsPath(SkPath*) const;
|
||||
// don't call
|
||||
GrRenderTarget* internal_private_accessTopLayerRenderTarget();
|
||||
|
||||
// don't call
|
||||
static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
|
||||
static bool Internal_Private_GetIgnoreSaveLayerBounds();
|
||||
static void Internal_Private_SetTreatSpriteAsBitmap(bool);
|
||||
static bool Internal_Private_GetTreatSpriteAsBitmap();
|
||||
|
||||
// TEMP helpers until we switch virtual over to const& for src-rect
|
||||
void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint* paint,
|
||||
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
|
||||
void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint* paint,
|
||||
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
|
||||
|
||||
protected:
|
||||
// default impl defers to getDevice()->newSurface(info)
|
||||
virtual SkSurface* onNewSurface(const SkImageInfo&);
|
||||
virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
|
||||
|
||||
// default impl defers to its device
|
||||
virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
|
||||
virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes);
|
||||
virtual bool onPeekPixels(SkPixmap*);
|
||||
virtual bool onAccessTopLayerPixels(SkPixmap*);
|
||||
|
||||
// Subclass save/restore notifiers.
|
||||
// Overriders should call the corresponding INHERITED method up the inheritance chain.
|
||||
@ -1182,6 +1234,7 @@ protected:
|
||||
return kFullLayer_SaveLayerStrategy;
|
||||
}
|
||||
virtual void willRestore() {}
|
||||
virtual void didRestore() {}
|
||||
virtual void didConcat(const SkMatrix&) {}
|
||||
virtual void didSetMatrix(const SkMatrix&) {}
|
||||
|
||||
@ -1201,6 +1254,39 @@ protected:
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
|
||||
virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint);
|
||||
|
||||
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
||||
|
||||
virtual void onDrawDrawable(SkDrawable*, const SkMatrix*);
|
||||
|
||||
virtual void onDrawPaint(const SkPaint&);
|
||||
virtual void onDrawRect(const SkRect&, const SkPaint&);
|
||||
virtual void onDrawOval(const SkRect&, const SkPaint&);
|
||||
virtual void onDrawRRect(const SkRRect&, const SkPaint&);
|
||||
virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&);
|
||||
virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
|
||||
const SkPoint texs[], const SkColor colors[], SkXfermode*,
|
||||
const uint16_t indices[], int indexCount, const SkPaint&);
|
||||
|
||||
virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*);
|
||||
virtual void onDrawPath(const SkPath&, const SkPaint&);
|
||||
virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
|
||||
virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
|
||||
SrcRectConstraint);
|
||||
virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
|
||||
virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*);
|
||||
virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
|
||||
SrcRectConstraint);
|
||||
virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
virtual void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*);
|
||||
|
||||
enum ClipEdgeStyle {
|
||||
kHard_ClipEdgeStyle,
|
||||
kSoft_ClipEdgeStyle
|
||||
@ -1213,7 +1299,7 @@ protected:
|
||||
|
||||
virtual void onDiscard();
|
||||
|
||||
virtual void onDrawPicture(const SkPicture* picture);
|
||||
virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
|
||||
|
||||
// Returns the canvas to be used by DrawIter. Default implementation
|
||||
// returns this. Subclasses that encapsulate an indirect canvas may
|
||||
@ -1229,30 +1315,40 @@ protected:
|
||||
SkIRect* intersection,
|
||||
const SkImageFilter* imageFilter = NULL);
|
||||
|
||||
// Called by child classes that override clipPath and clipRRect to only
|
||||
// track fast conservative clip bounds, rather than exact clips.
|
||||
void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op,
|
||||
bool inverseFilled);
|
||||
private:
|
||||
enum ShaderOverrideOpacity {
|
||||
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
|
||||
kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
|
||||
kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
|
||||
};
|
||||
|
||||
// notify our surface (if we have one) that we are about to draw, so it
|
||||
// can perform copy-on-write or invalidate any cached images
|
||||
void predrawNotify();
|
||||
void predrawNotify(bool willOverwritesEntireSurface = false);
|
||||
void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
|
||||
void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
|
||||
this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
|
||||
: kNotOpaque_ShaderOverrideOpacity);
|
||||
}
|
||||
|
||||
virtual void onPushCull(const SkRect& cullRect);
|
||||
virtual void onPopCull();
|
||||
|
||||
private:
|
||||
class MCRec;
|
||||
|
||||
SkClipStack fClipStack;
|
||||
SkAutoTUnref<SkClipStack> fClipStack;
|
||||
SkDeque fMCStack;
|
||||
// points to top of stack
|
||||
MCRec* fMCRec;
|
||||
// the first N recs that can fit here mean we won't call malloc
|
||||
uint32_t fMCRecStorage[32];
|
||||
enum {
|
||||
kMCRecSize = 128, // most recent measurement
|
||||
kMCRecCount = 32, // common depth for save/restores
|
||||
kDeviceCMSize = 136, // most recent measurement
|
||||
};
|
||||
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
|
||||
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
|
||||
|
||||
int fSaveLayerCount; // number of successful saveLayer calls
|
||||
int fCullCount; // number of active culls
|
||||
const SkSurfaceProps fProps;
|
||||
|
||||
int fSaveCount; // value returned by getSaveCount()
|
||||
|
||||
SkMetaData* fMetaData;
|
||||
|
||||
@ -1267,25 +1363,37 @@ private:
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
void updateDeviceCMCache();
|
||||
|
||||
void doSave();
|
||||
void checkForDeferredSave();
|
||||
|
||||
friend class SkDrawIter; // needs setupDrawForLayerDevice()
|
||||
friend class AutoDrawLooper;
|
||||
friend class SkLua; // needs top layer size and offset
|
||||
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
|
||||
friend class SkDeferredDevice; // needs getTopDevice()
|
||||
friend class SkSurface_Raster; // needs getDevice()
|
||||
friend class SkRecorder; // InitFlags
|
||||
friend class SkNoSaveLayerCanvas; // InitFlags
|
||||
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
|
||||
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
|
||||
|
||||
SkBaseDevice* createLayerDevice(const SkImageInfo&);
|
||||
enum InitFlags {
|
||||
kDefault_InitFlags = 0,
|
||||
kConservativeRasterClip_InitFlag = 1 << 0,
|
||||
};
|
||||
SkCanvas(const SkIRect& bounds, InitFlags);
|
||||
SkCanvas(SkBaseDevice* device, InitFlags);
|
||||
|
||||
SkBaseDevice* init(SkBaseDevice*);
|
||||
void resetForNextPicture(const SkIRect& bounds);
|
||||
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* Specify a device for this canvas to draw into. If it is not null, its
|
||||
* reference count is incremented. If the canvas was already holding a
|
||||
* device, its reference count is decremented. The new device is returned.
|
||||
*/
|
||||
SkBaseDevice* setRootDevice(SkBaseDevice* device);
|
||||
// needs gettotalclip()
|
||||
friend class SkCanvasStateUtils;
|
||||
|
||||
// call this each time we attach ourselves to a device
|
||||
// - constructor
|
||||
// - internalSaveLayer
|
||||
void setupDevice(SkBaseDevice*);
|
||||
|
||||
SkBaseDevice* init(SkBaseDevice*, InitFlags);
|
||||
|
||||
/**
|
||||
* Gets the size/origin of the top level layer in global canvas coordinates. We don't want this
|
||||
@ -1294,21 +1402,15 @@ private:
|
||||
SkISize getTopLayerSize() const;
|
||||
SkIPoint getTopLayerOrigin() const;
|
||||
|
||||
// internal methods are not virtual, so they can safely be called by other
|
||||
// canvas apis, without confusing subclasses (like SkPictureRecording)
|
||||
void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint);
|
||||
void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint* paint,
|
||||
DrawBitmapRectFlags flags);
|
||||
void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint* paint);
|
||||
SrcRectConstraint);
|
||||
void internalDrawPaint(const SkPaint& paint);
|
||||
int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
|
||||
void internalSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags, SaveLayerStrategy);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice);
|
||||
|
||||
// shared by save() and saveLayer()
|
||||
int internalSave();
|
||||
void internalSave();
|
||||
void internalRestore();
|
||||
static void DrawRect(const SkDraw& draw, const SkPaint& paint,
|
||||
const SkRect& r, SkScalar textSize);
|
||||
@ -1316,6 +1418,17 @@ private:
|
||||
const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y);
|
||||
|
||||
// only for canvasutils
|
||||
const SkRegion& internal_private_getTotalClip() const;
|
||||
|
||||
/*
|
||||
* Returns true if drawing the specified rect (or all if it is null) with the specified
|
||||
* paint (or default if null) would overwrite the entire root device of the canvas
|
||||
* (i.e. the canvas' surface if it had one).
|
||||
*/
|
||||
bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
|
||||
|
||||
|
||||
/* These maintain a cache of the clip bounds in local coordinates,
|
||||
(converted to 2s-compliment if floats are slow).
|
||||
*/
|
||||
@ -1323,6 +1436,7 @@ private:
|
||||
mutable bool fCachedLocalClipBoundsDirty;
|
||||
bool fAllowSoftClip;
|
||||
bool fAllowSimplifyClip;
|
||||
const bool fConservativeRasterClip;
|
||||
|
||||
const SkRect& getLocalClipBounds() const {
|
||||
if (fCachedLocalClipBoundsDirty) {
|
||||
@ -1346,9 +1460,6 @@ private:
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
// The cull stack rects are in device-space
|
||||
SkTDArray<SkIRect> fCullStack;
|
||||
void validateCull(const SkIRect&);
|
||||
void validateClip() const;
|
||||
#else
|
||||
void validateClip() const {}
|
||||
@ -1394,28 +1505,6 @@ private:
|
||||
};
|
||||
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
|
||||
|
||||
/** Stack helper class to automatically open and close a comment block
|
||||
*/
|
||||
class SkAutoCommentBlock : SkNoncopyable {
|
||||
public:
|
||||
SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
|
||||
fCanvas = canvas;
|
||||
if (NULL != fCanvas) {
|
||||
fCanvas->beginCommentGroup(description);
|
||||
}
|
||||
}
|
||||
|
||||
~SkAutoCommentBlock() {
|
||||
if (NULL != fCanvas) {
|
||||
fCanvas->endCommentGroup();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
};
|
||||
#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock)
|
||||
|
||||
/**
|
||||
* If the caller wants read-only access to the pixels in a canvas, it can just
|
||||
* call canvas->peekPixels(), since that is the fastest way to "peek" at the
|
||||
|
@ -22,6 +22,11 @@ public:
|
||||
* pointers.
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* Reset to 0 used bytes preserving as much memory as possible.
|
||||
* This invalidates all returned pointers.
|
||||
*/
|
||||
void rewind();
|
||||
|
||||
enum AllocFailType {
|
||||
kReturnNil_AllocFailType,
|
||||
@ -43,7 +48,8 @@ public:
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
size_t totalUsed() const { return fTotalUsed; }
|
||||
int blockCount() const { return fBlockCount; }
|
||||
SkDEBUGCODE(int blockCount() const { return fBlockCount; })
|
||||
SkDEBUGCODE(size_t totalLost() const { return fTotalLost; })
|
||||
|
||||
/**
|
||||
* Returns true if the specified address is within one of the chunks, and
|
||||
@ -60,9 +66,13 @@ private:
|
||||
size_t fChunkSize;
|
||||
size_t fTotalCapacity;
|
||||
size_t fTotalUsed; // will be <= fTotalCapacity
|
||||
int fBlockCount;
|
||||
SkDEBUGCODE(int fBlockCount;)
|
||||
SkDEBUGCODE(size_t fTotalLost;) // will be <= fTotalCapacity
|
||||
|
||||
Block* newBlock(size_t bytes, AllocFailType ftype);
|
||||
Block* addBlockIfNecessary(size_t bytes, AllocFailType ftype);
|
||||
|
||||
SkDEBUGCODE(void validate();)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@ class SkCanvasClipVisitor;
|
||||
// (i.e., the fSaveCount in force when it was added). Restores are thus
|
||||
// implemented by removing clips from fDeque that have an fSaveCount larger
|
||||
// then the freshly decremented count.
|
||||
class SK_API SkClipStack {
|
||||
class SK_API SkClipStack : public SkNVRefCnt<SkClipStack> {
|
||||
public:
|
||||
enum BoundsType {
|
||||
// The bounding box contains all the pixels that can be written to
|
||||
@ -309,13 +309,6 @@ public:
|
||||
BoundsType* boundType,
|
||||
bool* isIntersectionOfRects = NULL) const;
|
||||
|
||||
/**
|
||||
* Takes an input rect in device space and conservatively clips it to the
|
||||
* clip-stack. If false is returned then the rect does not intersect the
|
||||
* clip and is unmodified.
|
||||
*/
|
||||
bool intersectRectWithClip(SkRect* devRect) const;
|
||||
|
||||
/**
|
||||
* Returns true if the input rect in device space is entirely contained
|
||||
* by the clip. A return value of false does not guarantee that the rect
|
||||
@ -323,6 +316,12 @@ public:
|
||||
*/
|
||||
bool quickContains(const SkRect& devRect) const;
|
||||
|
||||
/**
|
||||
* Flattens the clip stack into a single SkPath. Returns true if any of
|
||||
* the clip stack components requires anti-aliasing.
|
||||
*/
|
||||
bool asPath(SkPath* path) const;
|
||||
|
||||
void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
|
||||
SkRect r;
|
||||
r.set(ir);
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -6,11 +5,11 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkColor_DEFINED
|
||||
#define SkColor_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkColor.h
|
||||
|
||||
@ -161,9 +160,4 @@ SK_API SkPMColor SkPreMultiplyColor(SkColor c);
|
||||
*/
|
||||
typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst);
|
||||
|
||||
/** Define a function pointer type for combining a premultiplied src color
|
||||
and a 16bit device color.
|
||||
*/
|
||||
typedef uint16_t (*SkXfermodeProc16)(SkPMColor src, uint16_t dst);
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -6,17 +5,17 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkColorFilter_DEFINED
|
||||
#define SkColorFilter_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class SkBitmap;
|
||||
class GrEffect;
|
||||
class GrContext;
|
||||
class GrFragmentProcessor;
|
||||
class SkBitmap;
|
||||
|
||||
/**
|
||||
* ColorFilters are optional objects in the drawing pipeline. When present in
|
||||
@ -28,8 +27,6 @@ class GrContext;
|
||||
*/
|
||||
class SK_API SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkColorFilter)
|
||||
|
||||
/**
|
||||
* If the filter can be represented by a source color plus Mode, this
|
||||
* returns true, and sets (if not NULL) the color and mode appropriately.
|
||||
@ -69,34 +66,27 @@ public:
|
||||
@param count the number of entries in the src[] and result[] arrays
|
||||
@param result written by the filter
|
||||
*/
|
||||
virtual void filterSpan(const SkPMColor src[], int count,
|
||||
SkPMColor result[]) const = 0;
|
||||
/** Called with a scanline of colors, as if there was a shader installed.
|
||||
The implementation writes out its filtered version into result[].
|
||||
Note: shader and result may be the same buffer.
|
||||
@param src array of colors, possibly generated by a shader
|
||||
@param count the number of entries in the src[] and result[] arrays
|
||||
@param result written by the filter
|
||||
*/
|
||||
virtual void filterSpan16(const uint16_t shader[], int count,
|
||||
uint16_t result[]) const;
|
||||
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0;
|
||||
|
||||
enum Flags {
|
||||
/** If set the filter methods will not change the alpha channel of the
|
||||
colors.
|
||||
/** If set the filter methods will not change the alpha channel of the colors.
|
||||
*/
|
||||
kAlphaUnchanged_Flag = 0x01,
|
||||
/** If set, this subclass implements filterSpan16(). If this flag is
|
||||
set, then kAlphaUnchanged_Flag must also be set.
|
||||
*/
|
||||
kHasFilter16_Flag = 0x02
|
||||
};
|
||||
|
||||
/** Returns the flags for this filter. Override in subclasses to return
|
||||
custom flags.
|
||||
/** Returns the flags for this filter. Override in subclasses to return custom flags.
|
||||
*/
|
||||
virtual uint32_t getFlags() const { return 0; }
|
||||
|
||||
/**
|
||||
* If this subclass can optimally createa composition with the inner filter, return it as
|
||||
* a new filter (which the caller must unref() when it is done). If no such optimization
|
||||
* is known, return NULL.
|
||||
*
|
||||
* e.g. result(color) == this_filter(inner(color))
|
||||
*/
|
||||
virtual SkColorFilter* newComposed(const SkColorFilter* /*inner*/) const { return NULL; }
|
||||
|
||||
/**
|
||||
* Apply this colorfilter to the specified SkColor. This routine handles
|
||||
* converting to SkPMColor, calling the filter, and then converting back
|
||||
@ -123,10 +113,31 @@ public:
|
||||
*/
|
||||
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
|
||||
|
||||
/** A subclass may implement this factory function to work with the GPU backend. If the return
|
||||
is non-NULL then the caller owns a ref on the returned object.
|
||||
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
|
||||
* the outer filter to the result of the inner's.
|
||||
* The reference counts for outer and inner are incremented.
|
||||
*
|
||||
* Due to internal limits, it is possible that this will return NULL, so the caller must
|
||||
* always check.
|
||||
*/
|
||||
virtual GrEffect* asNewEffect(GrContext*) const;
|
||||
static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner);
|
||||
|
||||
/**
|
||||
* A subclass may implement this factory function to work with the GPU backend. It returns
|
||||
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
|
||||
*
|
||||
* The fragment processor receives a premultiplied input color and produces a premultiplied
|
||||
* output color.
|
||||
*
|
||||
* A null return indicates that the color filter isn't implemented for the GPU backend.
|
||||
*/
|
||||
virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool affectsTransparentBlack() const {
|
||||
return this->filterColor(0) != 0;
|
||||
}
|
||||
|
||||
SK_TO_STRING_PUREVIRT()
|
||||
|
||||
@ -135,9 +146,18 @@ public:
|
||||
|
||||
protected:
|
||||
SkColorFilter() {}
|
||||
SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Returns 1 if this is a single filter (not a composition of other filters), otherwise it
|
||||
* reutrns the number of leaf-node filters in a composition. This should be the same value
|
||||
* as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter.
|
||||
*
|
||||
* e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4
|
||||
*/
|
||||
virtual int privateComposedFilterCount() const { return 1; }
|
||||
friend class SkComposeColorFilter;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
|
@ -193,7 +193,7 @@ static inline unsigned Sk255To256(U8CPU value) {
|
||||
/** Multiplify value by 0..256, and shift the result down 8
|
||||
(i.e. return (value * alpha256) >> 8)
|
||||
*/
|
||||
#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8)
|
||||
#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8)
|
||||
|
||||
// The caller may want negative values, so keep all params signed (int)
|
||||
// so we don't accidentally slip into unsigned math and lose the sign
|
||||
@ -213,11 +213,21 @@ static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) {
|
||||
SkASSERT((int16_t)dst == dst);
|
||||
SkASSERT((uint8_t)alpha == alpha);
|
||||
|
||||
int prod = SkMulS16(src - dst, alpha) + 128;
|
||||
int prod = (src - dst) * alpha + 128;
|
||||
prod = (prod + (prod >> 8)) >> 8;
|
||||
return dst + prod;
|
||||
}
|
||||
|
||||
static inline U8CPU SkUnitScalarClampToByte(SkScalar x) {
|
||||
if (x < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x >= SK_Scalar1) {
|
||||
return 255;
|
||||
}
|
||||
return SkScalarToFixed(x) >> 8;
|
||||
}
|
||||
|
||||
#define SK_R16_BITS 5
|
||||
#define SK_G16_BITS 6
|
||||
#define SK_B16_BITS 5
|
||||
@ -281,6 +291,16 @@ static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
|
||||
// this helper explicitly returns a clean 16bit value (but slower)
|
||||
#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s)
|
||||
|
||||
/** Blend pre-expanded RGB32 with 16bit color value by the 0..32 scale parameter.
|
||||
The computation yields only 16bits of valid data, but we claim to return
|
||||
32bits, so that the compiler won't generate extra instructions to "clean"
|
||||
the top 16bits.
|
||||
*/
|
||||
static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst, unsigned scale) {
|
||||
uint32_t dst_expand = SkExpand_rgb_16(dst) * scale;
|
||||
return SkCompact_rgb_16((src_expand + dst_expand) >> 5);
|
||||
}
|
||||
|
||||
/** Blend src and dst 16bit colors by the 0..256 scale parameter.
|
||||
The computation yields only 16bits of valid data, but we claim
|
||||
to return 32bits, so that the compiler won't generate extra instructions to
|
||||
@ -306,7 +326,8 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
|
||||
do {
|
||||
uint32_t src32 = SkExpand_rgb_16(*src++);
|
||||
uint32_t dst32 = SkExpand_rgb_16(*dst);
|
||||
*dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
|
||||
*dst++ = static_cast<uint16_t>(
|
||||
SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)));
|
||||
} while (--count > 0);
|
||||
}
|
||||
|
||||
@ -345,21 +366,31 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
|
||||
#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static inline void SkPMColorAssert(SkPMColor c) {
|
||||
unsigned a = SkGetPackedA32(c);
|
||||
unsigned r = SkGetPackedR32(c);
|
||||
unsigned g = SkGetPackedG32(c);
|
||||
unsigned b = SkGetPackedB32(c);
|
||||
|
||||
SkA32Assert(a);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
}
|
||||
#define SkPMColorAssert(color_value) \
|
||||
do { \
|
||||
SkPMColor pm_color_value = (color_value); \
|
||||
uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \
|
||||
SkA32Assert(alpha_color_value); \
|
||||
SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \
|
||||
SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \
|
||||
SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \
|
||||
} while (false)
|
||||
#else
|
||||
#define SkPMColorAssert(c)
|
||||
#endif
|
||||
|
||||
static inline bool SkPMColorValid(SkPMColor c) {
|
||||
auto a = SkGetPackedA32(c);
|
||||
bool valid = a <= SK_A32_MASK
|
||||
&& SkGetPackedR32(c) <= a
|
||||
&& SkGetPackedG32(c) <= a
|
||||
&& SkGetPackedB32(c) <= a;
|
||||
if (valid) {
|
||||
SkPMColorAssert(c); // Make sure we're consistent when it counts.
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the components into a SkPMColor, checking (in the debug version) that
|
||||
* the components are 0..255, and are already premultiplied (i.e. alpha >= color)
|
||||
@ -787,7 +818,7 @@ static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
|
||||
(g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
|
||||
}
|
||||
|
||||
static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
|
||||
static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) {
|
||||
SkASSERT(scale <= 16);
|
||||
|
||||
const unsigned mask = 0xF0F; //gMask_0F0F;
|
||||
@ -797,14 +828,14 @@ static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
|
||||
unsigned ag = ((c >> 4) & mask) * scale;
|
||||
return (rb & mask) | (ag & ~mask);
|
||||
#else
|
||||
c = (c & mask) | ((c & (mask << 4)) << 12);
|
||||
c = c * scale >> 4;
|
||||
return (c & mask) | ((c >> 12) & (mask << 4));
|
||||
unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12);
|
||||
unsigned scaled_c = (expanded_c * scale) >> 4;
|
||||
return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
|
||||
once by a value up to 16. Used in conjunction with SkCompact_4444.
|
||||
once by a value up to 16.
|
||||
*/
|
||||
static inline uint32_t SkExpand_4444(U16CPU c) {
|
||||
SkASSERT(c == (uint16_t)c);
|
||||
@ -813,18 +844,6 @@ static inline uint32_t SkExpand_4444(U16CPU c) {
|
||||
return (c & mask) | ((c & ~mask) << 12);
|
||||
}
|
||||
|
||||
/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
|
||||
NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
|
||||
It does this for speed, since if it is being written directly to 16bits of
|
||||
memory, the top 16bits will be ignored. Casting the result to uint16_t here
|
||||
would add 2 more instructions, slow us down. It is up to the caller to
|
||||
perform the cast if needed.
|
||||
*/
|
||||
static inline U16CPU SkCompact_4444(uint32_t c) {
|
||||
const unsigned mask = 0xF0F; //gMask_0F0F;
|
||||
return (c & mask) | ((c >> 12) & ~mask);
|
||||
}
|
||||
|
||||
static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
|
||||
unsigned sa = SkGetPackedA4444(s);
|
||||
unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
|
||||
@ -856,22 +875,6 @@ static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale1
|
||||
return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
|
||||
}
|
||||
|
||||
static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) {
|
||||
SkASSERT((unsigned)scale16 <= 16);
|
||||
|
||||
uint32_t src32 = SkExpand_4444(src) * scale16;
|
||||
// the scaled srcAlpha is the bottom byte
|
||||
#ifdef SK_DEBUG
|
||||
{
|
||||
unsigned srcA = SkGetPackedA4444(src) * scale16;
|
||||
SkASSERT(srcA == (src32 & 0xFF));
|
||||
}
|
||||
#endif
|
||||
unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
|
||||
uint32_t dst32 = SkExpand_4444(dst) * dstScale;
|
||||
return SkCompact_4444((src32 + dst32) >> 4);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) {
|
||||
uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
|
||||
(SkGetPackedR4444(c) << SK_R32_SHIFT) |
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef SkColorTable_DEFINED
|
||||
#define SkColorTable_DEFINED
|
||||
|
||||
#include "../private/SkOncePtr.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkImageInfo.h"
|
||||
@ -18,75 +19,64 @@
|
||||
|
||||
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
|
||||
8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
|
||||
*/
|
||||
class SkColorTable : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkColorTable)
|
||||
|
||||
/** Makes a deep copy of colors.
|
||||
SkColorTable is thread-safe.
|
||||
*/
|
||||
class SK_API SkColorTable : public SkRefCnt {
|
||||
public:
|
||||
/** Copy up to 256 colors into a new SkColorTable.
|
||||
*/
|
||||
SkColorTable(const SkColorTable& src);
|
||||
SkColorTable(const SkPMColor colors[], int count,
|
||||
SkAlphaType alphaType = kPremul_SkAlphaType);
|
||||
SkColorTable(const SkPMColor colors[], int count);
|
||||
virtual ~SkColorTable();
|
||||
|
||||
SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; }
|
||||
|
||||
bool isOpaque() const {
|
||||
return SkAlphaTypeIsOpaque(this->alphaType());
|
||||
}
|
||||
|
||||
/** Returns the number of colors in the table.
|
||||
*/
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/** Returns the specified color from the table. In the debug build, this asserts that
|
||||
the index is in range (0 <= index < count).
|
||||
*/
|
||||
* the index is in range (0 <= index < count).
|
||||
*/
|
||||
SkPMColor operator[](int index) const {
|
||||
SkASSERT(fColors != NULL && (unsigned)index < fCount);
|
||||
SkASSERT(fColors != NULL && (unsigned)index < (unsigned)fCount);
|
||||
return fColors[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array of colors for reading. This must be balanced by a call
|
||||
* to unlockColors().
|
||||
/** Return the array of colors for reading.
|
||||
*/
|
||||
const SkPMColor* lockColors() {
|
||||
SkDEBUGCODE(sk_atomic_inc(&fColorLockCount);)
|
||||
return fColors;
|
||||
}
|
||||
const SkPMColor* readColors() const { return fColors; }
|
||||
|
||||
/**
|
||||
* Balancing call to lockColors().
|
||||
/** read16BitCache() returns the array of RGB16 colors that mirror the 32bit colors.
|
||||
*/
|
||||
void unlockColors();
|
||||
const uint16_t* read16BitCache() const;
|
||||
|
||||
/** Similar to lockColors(), lock16BitCache() returns the array of
|
||||
RGB16 colors that mirror the 32bit colors. However, this function
|
||||
will return null if kColorsAreOpaque_Flag is not set.
|
||||
Also, unlike lockColors(), the returned array here cannot be modified.
|
||||
*/
|
||||
const uint16_t* lock16BitCache();
|
||||
/** Balancing call to lock16BitCache().
|
||||
*/
|
||||
void unlock16BitCache() {
|
||||
SkASSERT(f16BitCacheLockCount > 0);
|
||||
SkDEBUGCODE(f16BitCacheLockCount -= 1);
|
||||
}
|
||||
|
||||
explicit SkColorTable(SkReadBuffer&);
|
||||
void writeToBuffer(SkWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
SkPMColor* fColors;
|
||||
uint16_t* f16BitCache;
|
||||
uint16_t fCount;
|
||||
uint8_t fAlphaType;
|
||||
SkDEBUGCODE(int fColorLockCount;)
|
||||
SkDEBUGCODE(int f16BitCacheLockCount;)
|
||||
// may return null
|
||||
static SkColorTable* Create(SkReadBuffer&);
|
||||
|
||||
void inval16BitCache();
|
||||
private:
|
||||
enum AllocatedWithMalloc {
|
||||
kAllocatedWithMalloc
|
||||
};
|
||||
// assumes ownership of colors (assumes it was allocated w/ malloc)
|
||||
SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc);
|
||||
|
||||
SkPMColor* fColors;
|
||||
SkOncePtr<uint16_t[]> f16BitCache;
|
||||
int fCount;
|
||||
|
||||
void init(const SkPMColor* colors, int count);
|
||||
|
||||
friend class SkImageGenerator;
|
||||
// Only call if no other thread or cache has seen this table.
|
||||
void dangerous_overwriteColors(const SkPMColor newColors[], int count) {
|
||||
if (count < 0 || count > fCount) {
|
||||
sk_throw();
|
||||
}
|
||||
// assumes that f16BitCache nas NOT been initialized yet, so we don't try to update it
|
||||
memcpy(fColors, newColors, count * sizeof(SkPMColor));
|
||||
fCount = count; // update fCount, in case count is smaller
|
||||
}
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
@ -34,7 +34,14 @@ public:
|
||||
SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL);
|
||||
virtual ~SkComposeShader();
|
||||
|
||||
virtual size_t contextSize() const SK_OVERRIDE;
|
||||
size_t contextSize() const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
const SkMatrix& viewM,
|
||||
const SkMatrix* localMatrix,
|
||||
SkFilterQuality) const override;
|
||||
#endif
|
||||
|
||||
class ComposeShaderContext : public SkShader::Context {
|
||||
public:
|
||||
@ -48,7 +55,7 @@ public:
|
||||
|
||||
virtual ~ComposeShaderContext();
|
||||
|
||||
virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
|
||||
void shadeSpan(int x, int y, SkPMColor[], int count) override;
|
||||
|
||||
private:
|
||||
SkShader::Context* fShaderContextA;
|
||||
@ -62,15 +69,15 @@ public:
|
||||
SkShader* getShaderB() { return fShaderB; }
|
||||
#endif
|
||||
|
||||
virtual bool asACompose(ComposeRec* rec) const SK_OVERRIDE;
|
||||
bool asACompose(ComposeRec* rec) const override;
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
|
||||
|
||||
protected:
|
||||
SkComposeShader(SkReadBuffer& );
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
Context* onCreateContext(const ContextRec&, void*) const override;
|
||||
|
||||
private:
|
||||
SkShader* fShaderA;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
@ -6,14 +5,14 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SkData_DEFINED
|
||||
#define SkData_DEFINED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkFILE;
|
||||
class SkStream;
|
||||
|
||||
/**
|
||||
* SkData holds an immutable data buffer. Not only is the data immutable,
|
||||
@ -22,8 +21,6 @@ struct SkFILE;
|
||||
*/
|
||||
class SK_API SkData : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkData)
|
||||
|
||||
/**
|
||||
* Returns the number of bytes stored.
|
||||
*/
|
||||
@ -44,6 +41,19 @@ public:
|
||||
return reinterpret_cast<const uint8_t*>(fPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* USE WITH CAUTION.
|
||||
* This call will assert that the refcnt is 1, as a precaution against modifying the
|
||||
* contents when another client/thread has access to the data.
|
||||
*/
|
||||
void* writable_data() {
|
||||
if (fSize) {
|
||||
// only assert we're unique if we're not empty
|
||||
SkASSERT(this->unique());
|
||||
}
|
||||
return fPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to copy a range of the data into a caller-provided buffer.
|
||||
* Returns the actual number of bytes copied, after clamping offset and
|
||||
@ -60,15 +70,21 @@ public:
|
||||
|
||||
/**
|
||||
* Function that, if provided, will be called when the SkData goes out
|
||||
* of scope, allowing for custom allocation/freeing of the data.
|
||||
* of scope, allowing for custom allocation/freeing of the data's contents.
|
||||
*/
|
||||
typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
|
||||
typedef void (*ReleaseProc)(const void* ptr, void* context);
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified data
|
||||
*/
|
||||
static SkData* NewWithCopy(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* Create a new data with uninitialized contents. The caller should call writable_data()
|
||||
* to write into the buffer, but this must be done before another ref() is made.
|
||||
*/
|
||||
static SkData* NewUninitialized(size_t length);
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified c-string
|
||||
* (a null-terminated array of bytes). The returned SkData will have size()
|
||||
@ -78,11 +94,18 @@ public:
|
||||
static SkData* NewWithCString(const char cstr[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref, taking the data ptr as is, and using the
|
||||
* Create a new dataref, taking the ptr as is, and using the
|
||||
* releaseproc to free it. The proc may be NULL.
|
||||
*/
|
||||
static SkData* NewWithProc(const void* data, size_t length,
|
||||
ReleaseProc proc, void* context);
|
||||
static SkData* NewWithProc(const void* ptr, size_t length, ReleaseProc proc, void* context);
|
||||
|
||||
/**
|
||||
* Call this when the data parameter is already const and will outlive the lifetime of the
|
||||
* SkData. Suitable for with const globals.
|
||||
*/
|
||||
static SkData* NewWithoutCopy(const void* data, size_t length) {
|
||||
return NewWithProc(data, length, DummyReleaseProc, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new dataref from a pointer allocated by malloc. The Data object
|
||||
@ -97,13 +120,13 @@ public:
|
||||
static SkData* NewFromFileName(const char path[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref from a SkFILE.
|
||||
* This does not take ownership of the SkFILE, nor close it.
|
||||
* The caller is free to close the SkFILE at its convenience.
|
||||
* The SkFILE must be open for reading only.
|
||||
* Create a new dataref from a stdio FILE.
|
||||
* This does not take ownership of the FILE, nor close it.
|
||||
* The caller is free to close the FILE at its convenience.
|
||||
* The FILE must be open for reading only.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static SkData* NewFromFILE(SkFILE* f);
|
||||
static SkData* NewFromFILE(FILE* f);
|
||||
|
||||
/**
|
||||
* Create a new dataref from a file descriptor.
|
||||
@ -114,6 +137,13 @@ public:
|
||||
*/
|
||||
static SkData* NewFromFD(int fd);
|
||||
|
||||
/**
|
||||
* Attempt to read size bytes into a SkData. If the read succeeds, return the data,
|
||||
* else return NULL. Either way the stream's cursor may have been changed as a result
|
||||
* of calling read().
|
||||
*/
|
||||
static SkData* NewFromStream(SkStream*, size_t size);
|
||||
|
||||
/**
|
||||
* Create a new dataref using a subset of the data in the specified
|
||||
* src dataref.
|
||||
@ -129,16 +159,29 @@ public:
|
||||
private:
|
||||
ReleaseProc fReleaseProc;
|
||||
void* fReleaseProcContext;
|
||||
|
||||
const void* fPtr;
|
||||
void* fPtr;
|
||||
size_t fSize;
|
||||
|
||||
SkData(const void* ptr, size_t size, ReleaseProc, void* context);
|
||||
explicit SkData(size_t size); // inplace new/delete
|
||||
virtual ~SkData();
|
||||
|
||||
|
||||
// Objects of this type are sometimes created in a custom fashion using sk_malloc_throw and
|
||||
// therefore must be sk_freed. We overload new to also call sk_malloc_throw so that memory
|
||||
// can be unconditionally released using sk_free in an overloaded delete. Overloading regular
|
||||
// new means we must also overload placement new.
|
||||
void* operator new(size_t size) { return sk_malloc_throw(size); }
|
||||
void* operator new(size_t, void* p) { return p; }
|
||||
void operator delete(void* p) { sk_free(p); }
|
||||
|
||||
// Called the first time someone calls NewEmpty to initialize the singleton.
|
||||
static SkData* NewEmptyImpl();
|
||||
static void DeleteEmpty(SkData*);
|
||||
friend SkData* sk_new_empty_data();
|
||||
|
||||
// shared internal factory
|
||||
static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length);
|
||||
|
||||
static void DummyReleaseProc(const void*, void*) {}
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
@ -20,8 +20,6 @@
|
||||
*/
|
||||
class SK_API SkDataTable : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDataTable)
|
||||
|
||||
/**
|
||||
* Returns true if the table is empty (i.e. has no entries).
|
||||
*/
|
||||
|
@ -9,47 +9,31 @@
|
||||
#define SkDevice_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkDeviceProperties.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkClipStack;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
class SkMetaData;
|
||||
class SkRegion;
|
||||
|
||||
class GrRenderTarget;
|
||||
|
||||
class SK_API SkBaseDevice : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBaseDevice)
|
||||
|
||||
/**
|
||||
* Construct a new device.
|
||||
*/
|
||||
SkBaseDevice();
|
||||
|
||||
/**
|
||||
* Construct a new device.
|
||||
*/
|
||||
SkBaseDevice(const SkDeviceProperties& deviceProperties);
|
||||
|
||||
explicit SkBaseDevice(const SkSurfaceProps&);
|
||||
virtual ~SkBaseDevice();
|
||||
|
||||
SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
|
||||
|
||||
SkMetaData& getMetaData();
|
||||
|
||||
/** Return the image properties of the device. */
|
||||
virtual const SkDeviceProperties& getDeviceProperties() const {
|
||||
//Currently, all the properties are leaky.
|
||||
return fLeakyProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ImageInfo for this device. If the canvas is not backed by pixels
|
||||
* (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
|
||||
@ -67,6 +51,12 @@ public:
|
||||
bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
|
||||
}
|
||||
|
||||
SkIRect getGlobalBounds() const {
|
||||
SkIRect bounds;
|
||||
this->getGlobalBounds(&bounds);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return this->imageInfo().width();
|
||||
}
|
||||
@ -89,7 +79,22 @@ public:
|
||||
|
||||
bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
|
||||
|
||||
void* accessPixels(SkImageInfo* info, size_t* rowBytes);
|
||||
/**
|
||||
* Try to get write-access to the pixels behind the device. If successful, this returns true
|
||||
* and fills-out the pixmap parameter. On success it also bumps the genID of the underlying
|
||||
* bitmap.
|
||||
*
|
||||
* On failure, returns false and ignores the pixmap parameter.
|
||||
*/
|
||||
bool accessPixels(SkPixmap* pmap);
|
||||
|
||||
/**
|
||||
* Try to get read-only-access to the pixels behind the device. If successful, this returns
|
||||
* true and fills-out the pixmap parameter.
|
||||
*
|
||||
* On failure, returns false and ignores the pixmap parameter.
|
||||
*/
|
||||
bool peekPixels(SkPixmap*);
|
||||
|
||||
/**
|
||||
* Return the device's associated gpu render target, or NULL.
|
||||
@ -111,7 +116,6 @@ public:
|
||||
*/
|
||||
virtual void onAttachToCanvas(SkCanvas*) {
|
||||
SkASSERT(!fAttachedToCanvas);
|
||||
this->lockPixels();
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = true;
|
||||
#endif
|
||||
@ -125,30 +129,28 @@ public:
|
||||
*/
|
||||
virtual void onDetachFromCanvas() {
|
||||
SkASSERT(fAttachedToCanvas);
|
||||
this->unlockPixels();
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
enum Usage {
|
||||
kGeneral_Usage,
|
||||
kSaveLayer_Usage // <! internal use only
|
||||
enum TileUsage {
|
||||
kPossible_TileUsage, //!< the created device may be drawn tiled
|
||||
kNever_TileUsage, //!< the created device will never be drawn tiled
|
||||
};
|
||||
|
||||
struct TextFlags {
|
||||
uint32_t fFlags; // SkPaint::getFlags()
|
||||
SkPaint::Hinting fHinting;
|
||||
uint32_t fFlags; // SkPaint::getFlags()
|
||||
};
|
||||
|
||||
/**
|
||||
* Device may filter the text flags for drawing text here. If it wants to
|
||||
* make a change to the specified values, it should write them into the
|
||||
* textflags parameter (output) and return true. If the paint is fine as
|
||||
* is, then ignore the textflags parameter and return false.
|
||||
* Returns the text-related flags, possibly modified based on the state of the
|
||||
* device (e.g. support for LCD).
|
||||
*/
|
||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) { return false; }
|
||||
uint32_t filterTextFlags(const SkPaint&) const;
|
||||
|
||||
virtual bool onShouldDisableLCD(const SkPaint&) const { return false; }
|
||||
|
||||
/**
|
||||
*
|
||||
@ -169,14 +171,6 @@ protected:
|
||||
virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
|
||||
const SkClipStack&) {};
|
||||
|
||||
/** Clears the entire device to the specified color (including alpha).
|
||||
* Ignores the clip.
|
||||
*/
|
||||
virtual void clear(SkColor color) = 0;
|
||||
|
||||
SK_ATTR_DEPRECATED("use clear() instead")
|
||||
void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
@ -223,7 +217,15 @@ protected:
|
||||
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::DrawBitmapRectFlags flags) = 0;
|
||||
SkCanvas::SrcRectConstraint) = 0;
|
||||
virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
|
||||
virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint);
|
||||
virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
@ -232,22 +234,33 @@ protected:
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) = 0;
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPos, const SkPaint& paint) = 0;
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) = 0;
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) = 0;
|
||||
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) = 0;
|
||||
// default implementation unrolls the blob runs.
|
||||
virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter);
|
||||
// default implementation calls drawVertices
|
||||
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
||||
|
||||
// default implementation calls drawPath
|
||||
virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkXfermode::Mode, const SkPaint&);
|
||||
|
||||
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||
onCreateDevice on this device with kSaveLayer_Usage.
|
||||
onCreateDevice on this device with kNeverTile_TileExpectation.
|
||||
*/
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) = 0;
|
||||
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
|
||||
const SkMatrix*, const SkPaint&);
|
||||
|
||||
bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -258,20 +271,6 @@ protected:
|
||||
*/
|
||||
virtual const SkBitmap& onAccessBitmap() = 0;
|
||||
|
||||
/** Called when this device is installed into a Canvas. Balanced by a call
|
||||
to unlockPixels() when the device is removed from a Canvas.
|
||||
*/
|
||||
virtual void lockPixels() {}
|
||||
virtual void unlockPixels() {}
|
||||
|
||||
/**
|
||||
* Returns true if the device allows processing of this imagefilter. If
|
||||
* false is returned, then the filter is ignored. This may happen for
|
||||
* some subclasses that do not support pixel manipulations after drawing
|
||||
* has occurred (e.g. printing). The default implementation returns true.
|
||||
*/
|
||||
virtual bool allowImageFilter(const SkImageFilter*) { return true; }
|
||||
|
||||
/**
|
||||
* Override and return true for filters that the device can handle
|
||||
* intrinsically. Doing so means that SkCanvas will pass-through this
|
||||
@ -289,17 +288,14 @@ protected:
|
||||
* it just returns false and leaves result and offset unchanged.
|
||||
*/
|
||||
virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
|
||||
const SkImageFilter::Context& ctx,
|
||||
SkBitmap* result, SkIPoint* offset) {
|
||||
const SkImageFilter::Context&,
|
||||
SkBitmap* /*result*/, SkIPoint* /*offset*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
// default impl returns NULL
|
||||
virtual SkSurface* newSurface(const SkImageInfo&);
|
||||
|
||||
// default impl returns NULL
|
||||
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
|
||||
virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; }
|
||||
virtual bool onPeekPixels(SkPixmap*) { return false; }
|
||||
|
||||
/**
|
||||
* The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
|
||||
@ -317,24 +313,11 @@ protected:
|
||||
*/
|
||||
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
|
||||
|
||||
/**
|
||||
* Default impl returns NULL.
|
||||
*/
|
||||
virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes);
|
||||
virtual bool onAccessPixels(SkPixmap*) { return false; }
|
||||
|
||||
/**
|
||||
* Leaky properties are those which the device should be applying but it isn't.
|
||||
* These properties will be applied by the draw, when and as it can.
|
||||
* If the device does handle a property, that property should be set to the identity value
|
||||
* for that property, effectively making it non-leaky.
|
||||
*/
|
||||
SkDeviceProperties fLeakyProperties;
|
||||
|
||||
/**
|
||||
* PRIVATE / EXPERIMENTAL -- do not call
|
||||
* Construct an acceleration object and attach it to 'picture'
|
||||
*/
|
||||
virtual void EXPERIMENTAL_optimize(const SkPicture* picture);
|
||||
const SkSurfaceProps& surfaceProps() const {
|
||||
return fSurfaceProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* PRIVATE / EXPERIMENTAL -- do not call
|
||||
@ -346,7 +329,42 @@ protected:
|
||||
* to perform some device-specific warm up tasks and then let SkCanvas
|
||||
* perform the main rendering loop (by return false from here).
|
||||
*/
|
||||
virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture);
|
||||
virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
|
||||
const SkPaint*);
|
||||
|
||||
struct CreateInfo {
|
||||
static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry);
|
||||
|
||||
// The constructor may change the pixel geometry based on other parameters.
|
||||
CreateInfo(const SkImageInfo& info,
|
||||
TileUsage tileUsage,
|
||||
SkPixelGeometry geo,
|
||||
bool forImageFilter = false)
|
||||
: fInfo(info)
|
||||
, fTileUsage(tileUsage)
|
||||
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo))
|
||||
, fForImageFilter(forImageFilter) {}
|
||||
|
||||
const SkImageInfo fInfo;
|
||||
const TileUsage fTileUsage;
|
||||
const SkPixelGeometry fPixelGeometry;
|
||||
const bool fForImageFilter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new device based on CreateInfo. If the paint is not null, then it represents a
|
||||
* preview of how the new device will be composed with its creator device (this).
|
||||
*
|
||||
* The subclass may be handed this device in drawDevice(), so it must always return
|
||||
* a device that it knows how to draw, and that it knows how to identify if it is not of the
|
||||
* same subclass (since drawDevice is passed a SkBaseDevice*). If the subclass cannot fulfill
|
||||
* that contract (e.g. PDF cannot support some settings on the paint) it should return NULL,
|
||||
* and the caller may then decide to explicitly create a bitmapdevice, knowing that later
|
||||
* it could not call drawDevice with it (but it could call drawSprite or drawBitmap).
|
||||
*/
|
||||
virtual SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
@ -354,8 +372,8 @@ private:
|
||||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
friend class SkDeviceImageFilterProxy;
|
||||
friend class SkDeferredDevice; // for newSurface
|
||||
friend class SkImageFilter::DeviceProxy;
|
||||
friend class SkNoPixelsBitmapDevice;
|
||||
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
@ -365,21 +383,20 @@ private:
|
||||
// TODO: move to SkBitmapDevice
|
||||
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
|
||||
|
||||
virtual bool forceConservativeRasterClip() const { return false; }
|
||||
|
||||
// just called by SkCanvas when built as a layer
|
||||
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
||||
// just called by SkCanvas for saveLayer
|
||||
SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
|
||||
|
||||
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Causes any deferred drawing to the device to be completed.
|
||||
*/
|
||||
virtual void flush() {}
|
||||
|
||||
virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; }
|
||||
|
||||
SkIPoint fOrigin;
|
||||
SkMetaData* fMetaData;
|
||||
SkSurfaceProps fSurfaceProps;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool fAttachedToCanvas;
|
||||
|
@ -1,103 +0,0 @@
|
||||
#ifndef SkDeviceProperties_DEFINED
|
||||
#define SkDeviceProperties_DEFINED
|
||||
|
||||
//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import.
|
||||
#include "SkFontLCDConfig.h"
|
||||
|
||||
struct SkDeviceProperties {
|
||||
struct Geometry {
|
||||
/** The orientation of the pixel specifies the interpretation of the
|
||||
* layout. If the orientation is horizontal, the layout is interpreted as
|
||||
* left to right. It the orientation is vertical, the layout is
|
||||
* interpreted top to bottom (rotated 90deg cw from horizontal).
|
||||
*/
|
||||
enum Orientation {
|
||||
kUnknown_Orientation = 0x0,
|
||||
kKnown_Orientation = 0x2,
|
||||
|
||||
kHorizontal_Orientation = 0x2, //!< this is the default
|
||||
kVertical_Orientation = 0x3,
|
||||
|
||||
kOrientationMask = 0x3,
|
||||
};
|
||||
|
||||
/** The layout of the pixel specifies its subpixel geometry.
|
||||
*
|
||||
* kUnknown_Layout means that the subpixel elements are not spatially
|
||||
* separated in any known or usable fashion.
|
||||
*/
|
||||
enum Layout {
|
||||
kUnknown_Layout = 0x0,
|
||||
kKnown_Layout = 0x8,
|
||||
|
||||
kRGB_Layout = 0x8, //!< this is the default
|
||||
kBGR_Layout = 0xC,
|
||||
|
||||
kLayoutMask = 0xC,
|
||||
};
|
||||
|
||||
Orientation getOrientation() {
|
||||
return static_cast<Orientation>(fGeometry & kOrientationMask);
|
||||
}
|
||||
Layout getLayout() {
|
||||
return static_cast<Layout>(fGeometry & kLayoutMask);
|
||||
}
|
||||
|
||||
bool isOrientationKnown() {
|
||||
return SkToBool(fGeometry & kKnown_Orientation);
|
||||
}
|
||||
bool isLayoutKnown() {
|
||||
return SkToBool(fGeometry & kKnown_Layout);
|
||||
}
|
||||
|
||||
private:
|
||||
//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants.
|
||||
static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) {
|
||||
switch (orientation) {
|
||||
case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation;
|
||||
case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation;
|
||||
default: return kUnknown_Orientation;
|
||||
}
|
||||
}
|
||||
static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) {
|
||||
switch (order) {
|
||||
case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout;
|
||||
case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout;
|
||||
default: return kUnknown_Layout;
|
||||
}
|
||||
}
|
||||
public:
|
||||
static Geometry MakeDefault() {
|
||||
Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation
|
||||
Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout
|
||||
Geometry ret = { SkToU8(orientation | layout) };
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Geometry Make(Orientation orientation, Layout layout) {
|
||||
Geometry ret = { SkToU8(orientation | layout) };
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t fGeometry;
|
||||
};
|
||||
|
||||
static SkDeviceProperties MakeDefault() {
|
||||
SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT };
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) {
|
||||
SkDeviceProperties ret = { geometry, gamma };
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Each pixel of an image will have some number of channels.
|
||||
* Can the layout of those channels be exploited? */
|
||||
Geometry fGeometry;
|
||||
|
||||
/** Represents the color space of the image. This is a woefully inadequate beginning. */
|
||||
SkScalar fGamma;
|
||||
};
|
||||
|
||||
#endif
|
@ -12,6 +12,8 @@
|
||||
#include "SkPicture.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTime.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkWStream;
|
||||
@ -30,56 +32,50 @@ class SkWStream;
|
||||
* c. doc->endPage();
|
||||
* 3. Close the document with doc->close().
|
||||
*/
|
||||
class SkDocument : public SkRefCnt {
|
||||
class SK_API SkDocument : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDocument)
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a SkWStream.
|
||||
*
|
||||
* PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm.
|
||||
*
|
||||
* @param SkWStream* A PDF document will be written to this
|
||||
* stream. The document may write to the stream at
|
||||
* anytime during its lifetime, until either close() is
|
||||
* called or the document is deleted.
|
||||
* @param dpi The DPI (pixels-per-inch) at which features without
|
||||
* native PDF support will be rasterized (e.g. draw image
|
||||
* with perspective, draw text with perspective, ...) A
|
||||
* larger DPI would create a PDF that reflects the
|
||||
* original intent with better fidelity, but it can make
|
||||
* for larger PDF files too, which would use more memory
|
||||
* while rendering, and it would be slower to be processed
|
||||
* or sent online or to printer.
|
||||
* @returns NULL if there is an error, otherwise a newly created
|
||||
* PDF-backed SkDocument.
|
||||
*/
|
||||
static SkDocument* CreatePDF(SkWStream*,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a file.
|
||||
* If there is an error trying to create the doc, returns NULL.
|
||||
* encoder sets the DCTEncoder for images, to encode a bitmap
|
||||
* as JPEG (DCT).
|
||||
* rasterDpi - the DPI at which features without native PDF support
|
||||
* will be rasterized (e.g. draw image with perspective,
|
||||
* draw text with perspective, ...)
|
||||
* A larger DPI would create a PDF that reflects the original
|
||||
* intent with better fidelity, but it can make for larger
|
||||
* PDF files too, which would use more memory while rendering,
|
||||
* and it would be slower to be processed or sent online or
|
||||
* to printer.
|
||||
*/
|
||||
static SkDocument* CreatePDF(
|
||||
const char filename[],
|
||||
SkPicture::EncodeBitmap encoder = NULL,
|
||||
SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
|
||||
static SkDocument* CreatePDF(const char outputFilePath[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a stream.
|
||||
* If there is an error trying to create the doc, returns NULL.
|
||||
*
|
||||
* The document may write to the stream at anytime during its lifetime,
|
||||
* until either close() is called or the document is deleted. Once close()
|
||||
* has been called, and all of the data has been written to the stream,
|
||||
* if there is a Done proc provided, it will be called with the stream.
|
||||
* The proc can delete the stream, or whatever it needs to do.
|
||||
* encoder sets the DCTEncoder for images, to encode a bitmap
|
||||
* as JPEG (DCT).
|
||||
* Done - clean up method intended to allow deletion of the stream.
|
||||
* Its aborted parameter is true if the cleanup is due to an abort
|
||||
* call. It is false otherwise.
|
||||
* rasterDpi - the DPI at which features without native PDF support
|
||||
* will be rasterized (e.g. draw image with perspective,
|
||||
* draw text with perspective, ...)
|
||||
* A larger DPI would create a PDF that reflects the original
|
||||
* intent with better fidelity, but it can make for larger
|
||||
* PDF files too, which would use more memory while rendering,
|
||||
* and it would be slower to be processed or sent online or
|
||||
* to printer. */
|
||||
static SkDocument* CreatePDF(
|
||||
SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL,
|
||||
SkPicture::EncodeBitmap encoder = NULL,
|
||||
SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
|
||||
* Create a XPS-backed document, writing the results into the stream.
|
||||
* Returns NULL if XPS is not supported.
|
||||
*/
|
||||
static SkDocument* CreateXPS(SkWStream* stream,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Create a XPS-backed document, writing the results into a file.
|
||||
* Returns NULL if XPS is not supported.
|
||||
*/
|
||||
static SkDocument* CreateXPS(const char path[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
/**
|
||||
* Begin a new page for the document, returning the canvas that will draw
|
||||
* into the page. The document owns this canvas, and it will go out of
|
||||
@ -110,8 +106,36 @@ public:
|
||||
*/
|
||||
void abort();
|
||||
|
||||
/**
|
||||
* Set the document's metadata, if supported by the document
|
||||
* type. The creationDate and modifiedDate parameters can be
|
||||
* nullptr. For example:
|
||||
*
|
||||
* SkDocument* make_doc(SkWStream* output) {
|
||||
* SkTArray<SkDocument::Attribute> info;
|
||||
* info.emplace_back(SkString("Title"), SkString("..."));
|
||||
* info.emplace_back(SkString("Author"), SkString("..."));
|
||||
* info.emplace_back(SkString("Subject"), SkString("..."));
|
||||
* info.emplace_back(SkString("Keywords"), SkString("..."));
|
||||
* info.emplace_back(SkString("Creator"), SkString("..."));
|
||||
* SkTime::DateTime now;
|
||||
* SkTime::GetDateTime(&now);
|
||||
* SkDocument* doc = SkDocument::CreatePDF(output);
|
||||
* doc->setMetadata(info, &now, &now);
|
||||
* return doc;
|
||||
* }
|
||||
*/
|
||||
struct Attribute {
|
||||
SkString fKey, fValue;
|
||||
Attribute(const SkString& k, const SkString& v) : fKey(k), fValue(v) {}
|
||||
};
|
||||
virtual void setMetadata(const SkTArray<SkDocument::Attribute>&,
|
||||
const SkTime::DateTime* /* creationDate */,
|
||||
const SkTime::DateTime* /* modifiedDate */) {}
|
||||
|
||||
protected:
|
||||
SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted));
|
||||
|
||||
// note: subclasses must call close() in their destructor, as the base class
|
||||
// cannot do this for them.
|
||||
virtual ~SkDocument();
|
||||
@ -122,6 +146,9 @@ protected:
|
||||
virtual bool onClose(SkWStream*) = 0;
|
||||
virtual void onAbort() = 0;
|
||||
|
||||
// Allows subclasses to write to the stream as pages are written.
|
||||
SkWStream* getStream() { return fStream; }
|
||||
|
||||
enum State {
|
||||
kBetweenPages_State,
|
||||
kInPage_State,
|
||||
|
@ -17,6 +17,7 @@
|
||||
class SkBitmap;
|
||||
class SkClipStack;
|
||||
class SkBaseDevice;
|
||||
class SkBlitter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
@ -33,7 +34,11 @@ public:
|
||||
void drawPaint(const SkPaint&) const;
|
||||
void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
|
||||
const SkPaint&, bool forceUseDevice = false) const;
|
||||
void drawRect(const SkRect&, const SkPaint&) const;
|
||||
void drawRect(const SkRect& prePaintRect, const SkPaint&, const SkMatrix* paintMatrix,
|
||||
const SkRect* postPaintRect) const;
|
||||
void drawRect(const SkRect& rect, const SkPaint& paint) const {
|
||||
this->drawRect(rect, paint, NULL, NULL);
|
||||
}
|
||||
void drawRRect(const SkRRect&, const SkPaint&) const;
|
||||
/**
|
||||
* To save on mallocs, we allow a flag that tells us that srcPath is
|
||||
@ -49,19 +54,20 @@ public:
|
||||
this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
|
||||
}
|
||||
|
||||
void drawPath(const SkPath& path, const SkPaint& paint) const {
|
||||
this->drawPath(path, paint, NULL, false, false);
|
||||
void drawPath(const SkPath& path, const SkPaint& paint,
|
||||
SkBlitter* customBlitter = NULL) const {
|
||||
this->drawPath(path, paint, NULL, false, false, customBlitter);
|
||||
}
|
||||
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
|
||||
/* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
|
||||
const SkPaint&) const;
|
||||
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
|
||||
void drawText(const char text[], size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint& paint) const;
|
||||
void drawPosText(const char text[], size_t byteLength,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPosition, const SkPaint& paint) const;
|
||||
void drawTextOnPath(const char text[], size_t byteLength,
|
||||
const SkPath&, const SkMatrix*, const SkPaint&) const;
|
||||
const SkScalar pos[], int scalarsPerPosition,
|
||||
const SkPoint& offset, const SkPaint& paint) const;
|
||||
void drawVertices(SkCanvas::VertexMode mode, int count,
|
||||
const SkPoint vertices[], const SkPoint textures[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
@ -74,8 +80,9 @@ public:
|
||||
*
|
||||
* Only device A8 is supported right now.
|
||||
*/
|
||||
void drawPathCoverage(const SkPath& src, const SkPaint& paint) const {
|
||||
this->drawPath(src, paint, NULL, false, true);
|
||||
void drawPathCoverage(const SkPath& src, const SkPaint& paint,
|
||||
SkBlitter* customBlitter = NULL) const {
|
||||
this->drawPath(src, paint, NULL, false, true, customBlitter);
|
||||
}
|
||||
|
||||
/** Helper function that creates a mask from a path and an optional maskfilter.
|
||||
@ -110,15 +117,16 @@ public:
|
||||
void drawText_asPaths(const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint&) const;
|
||||
void drawPosText_asPaths(const char text[], size_t byteLength,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPosition, const SkPaint&) const;
|
||||
const SkScalar pos[], int scalarsPerPosition,
|
||||
const SkPoint& offset, const SkPaint&) const;
|
||||
|
||||
private:
|
||||
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
||||
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
|
||||
|
||||
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
|
||||
bool pathIsMutable, bool drawCoverage) const;
|
||||
bool pathIsMutable, bool drawCoverage,
|
||||
SkBlitter* customBlitter = NULL) const;
|
||||
|
||||
/**
|
||||
* Return the current clip bounds, in local coordinates, with slop to account
|
||||
@ -132,14 +140,13 @@ private:
|
||||
computeConservativeLocalClipBounds(SkRect* bounds) const;
|
||||
|
||||
public:
|
||||
const SkBitmap* fBitmap; // required
|
||||
SkPixmap fDst;
|
||||
const SkMatrix* fMatrix; // required
|
||||
const SkRegion* fClip; // DEPRECATED
|
||||
const SkRasterClip* fRC; // required
|
||||
|
||||
const SkClipStack* fClipStack; // optional
|
||||
SkBaseDevice* fDevice; // optional
|
||||
SkDrawProcs* fProcs; // optional
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
|
@ -23,8 +23,6 @@ class SkPaint;
|
||||
*/
|
||||
class SK_API SkDrawFilter : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDrawFilter)
|
||||
|
||||
enum Type {
|
||||
kPaint_Type,
|
||||
kPoint_Type,
|
||||
|
@ -30,8 +30,6 @@ class SkString;
|
||||
*/
|
||||
class SK_API SkDrawLooper : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDrawLooper)
|
||||
|
||||
/**
|
||||
* Holds state during a draw. Users call next() until it returns false.
|
||||
*
|
||||
@ -87,9 +85,8 @@ public:
|
||||
* storage rect, where the storage rect is with the union of the src rect
|
||||
* and the looper's bounding rect.
|
||||
*/
|
||||
virtual bool canComputeFastBounds(const SkPaint& paint) const;
|
||||
virtual void computeFastBounds(const SkPaint& paint,
|
||||
const SkRect& src, SkRect* dst) const;
|
||||
bool canComputeFastBounds(const SkPaint& paint) const;
|
||||
void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;
|
||||
|
||||
struct BlurShadowRec {
|
||||
SkScalar fSigma;
|
||||
@ -114,7 +111,6 @@ public:
|
||||
|
||||
protected:
|
||||
SkDrawLooper() {}
|
||||
SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawPictureCallback_DEFINED
|
||||
#define SkDrawPictureCallback_DEFINED
|
||||
|
||||
/**
|
||||
* Subclasses of this can be passed to canvas.drawPicture(). During the drawing
|
||||
* of the picture, this callback will periodically be invoked. If its
|
||||
* abortDrawing() returns true, then picture playback will be interrupted.
|
||||
*
|
||||
* The resulting drawing is undefined, as there is no guarantee how often the
|
||||
* callback will be invoked. If the abort happens inside some level of nested
|
||||
* calls to save(), restore will automatically be called to return the state
|
||||
* to the same level it was before the drawPicture call was made.
|
||||
*/
|
||||
class SK_API SkDrawPictureCallback {
|
||||
public:
|
||||
SkDrawPictureCallback() {}
|
||||
virtual ~SkDrawPictureCallback() {}
|
||||
|
||||
virtual bool abortDrawing() = 0;
|
||||
};
|
||||
|
||||
#endif//SkDrawPictureCallback_DEFINED
|
77
gfx/skia/skia/include/core/SkDrawable.h
Normal file
77
gfx/skia/skia/include/core/SkDrawable.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawable_DEFINED
|
||||
#define SkDrawable_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkPicture;
|
||||
struct SkRect;
|
||||
|
||||
/**
|
||||
* Base-class for objects that draw into SkCanvas.
|
||||
*
|
||||
* The object has a generation ID, which is guaranteed to be unique across all drawables. To
|
||||
* allow for clients of the drawable that may want to cache the results, the drawable must
|
||||
* change its generation ID whenever its internal state changes such that it will draw differently.
|
||||
*/
|
||||
class SkDrawable : public SkRefCnt {
|
||||
public:
|
||||
SkDrawable();
|
||||
|
||||
/**
|
||||
* Draws into the specified content. The drawing sequence will be balanced upon return
|
||||
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
|
||||
* and the current matrix and clip settings will not be changed.
|
||||
*/
|
||||
void draw(SkCanvas*, const SkMatrix* = NULL);
|
||||
void draw(SkCanvas*, SkScalar x, SkScalar y);
|
||||
|
||||
SkPicture* newPictureSnapshot();
|
||||
|
||||
/**
|
||||
* Return a unique value for this instance. If two calls to this return the same value,
|
||||
* it is presumed that calling the draw() method will render the same thing as well.
|
||||
*
|
||||
* Subclasses that change their state should call notifyDrawingChanged() to ensure that
|
||||
* a new value will be returned the next time it is called.
|
||||
*/
|
||||
uint32_t getGenerationID();
|
||||
|
||||
/**
|
||||
* Return the (conservative) bounds of what the drawable will draw. If the drawable can
|
||||
* change what it draws (e.g. animation or in response to some external change), then this
|
||||
* must return a bounds that is always valid for all possible states.
|
||||
*/
|
||||
SkRect getBounds();
|
||||
|
||||
/**
|
||||
* Calling this invalidates the previous generation ID, and causes a new one to be computed
|
||||
* the next time getGenerationID() is called. Typically this is called by the object itself,
|
||||
* in response to its internal state changing.
|
||||
*/
|
||||
void notifyDrawingChanged();
|
||||
|
||||
protected:
|
||||
virtual SkRect onGetBounds() = 0;
|
||||
virtual void onDraw(SkCanvas*) = 0;
|
||||
|
||||
/**
|
||||
* Default implementation calls onDraw() with a canvas that records into a picture. Subclasses
|
||||
* may override if they have a more efficient way to return a picture for the current state
|
||||
* of their drawable. Note: this picture must draw the same as what would be drawn from
|
||||
* onDraw().
|
||||
*/
|
||||
virtual SkPicture* onNewPictureSnapshot();
|
||||
|
||||
private:
|
||||
int32_t fGenerationID;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDynamicAnnotations_DEFINED
|
||||
#define SkDynamicAnnotations_DEFINED
|
||||
|
||||
// This file contains macros used to send out-of-band signals to dynamic instrumentation systems,
|
||||
// namely thread sanitizer. This is a cut-down version of the full dynamic_annotations library with
|
||||
// only the features used by Skia.
|
||||
|
||||
#if SK_DYNAMIC_ANNOTATIONS_ENABLED
|
||||
|
||||
extern "C" {
|
||||
// TSAN provides these hooks.
|
||||
void AnnotateIgnoreReadsBegin(const char* file, int line);
|
||||
void AnnotateIgnoreReadsEnd(const char* file, int line);
|
||||
void AnnotateIgnoreWritesBegin(const char* file, int line);
|
||||
void AnnotateIgnoreWritesEnd(const char* file, int line);
|
||||
void AnnotateBenignRaceSized(const char* file, int line,
|
||||
const volatile void* addr, long size, const char* desc);
|
||||
} // extern "C"
|
||||
|
||||
// SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to
|
||||
// be a racy read. This should be used only when we can make an external guarantee that though this
|
||||
// particular read is racy, it is being used as part of a mechanism which is thread safe. Examples:
|
||||
// - the first check in double-checked locking;
|
||||
// - checking if a ref count is equal to 1.
|
||||
// Note that in both these cases, we must still add terrifyingly subtle memory barriers to provide
|
||||
// that overall thread safety guarantee. Using this macro to shut TSAN up without providing such an
|
||||
// external guarantee is pretty much never correct.
|
||||
template <typename T>
|
||||
inline T SK_ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
|
||||
AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
|
||||
T read = x;
|
||||
AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
|
||||
return read;
|
||||
}
|
||||
|
||||
// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes.
|
||||
template <typename T>
|
||||
inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const volatile T& val) {
|
||||
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
|
||||
*ptr = val;
|
||||
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// Ignore racy reads and racy writes to this pointer, indefinitely.
|
||||
// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ.
|
||||
template <typename T>
|
||||
void SK_ANNOTATE_BENIGN_RACE(T* ptr) {
|
||||
AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE");
|
||||
}
|
||||
|
||||
#else // !SK_DYNAMIC_ANNOTATIONS_ENABLED
|
||||
|
||||
#define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
|
||||
#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
|
||||
#define SK_ANNOTATE_BENIGN_RACE(ptr)
|
||||
|
||||
#endif
|
||||
|
||||
// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g.
|
||||
// - SkMatrix type mask
|
||||
// - SkPixelRef genIDs
|
||||
template <typename T>
|
||||
class SkTRacy {
|
||||
public:
|
||||
operator const T() const {
|
||||
return SK_ANNOTATE_UNPROTECTED_READ(fVal);
|
||||
}
|
||||
|
||||
SkTRacy& operator=(const T& val) {
|
||||
SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T fVal;
|
||||
};
|
||||
|
||||
// This is like SkTRacy, but allows you to return the value by reference.
|
||||
// TSAN is better at suppressing SkTRacy than SkTRacyReffable, so use SkTRacy when possible.
|
||||
//
|
||||
// We use this for SkPathRef bounds, which is an SkRect we pass around by reference publically.
|
||||
template <typename T>
|
||||
class SkTRacyReffable {
|
||||
public:
|
||||
SkTRacyReffable() { SK_ANNOTATE_BENIGN_RACE(&fVal); }
|
||||
|
||||
operator const T&() const {
|
||||
return fVal;
|
||||
}
|
||||
|
||||
SkTRacyReffable& operator=(const T& val) {
|
||||
fVal = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T* get() const { return &fVal; }
|
||||
T* get() { return &fVal; }
|
||||
|
||||
const T* operator->() const { return &fVal; }
|
||||
T* operator->() { return &fVal; }
|
||||
|
||||
private:
|
||||
T fVal;
|
||||
};
|
||||
|
||||
#endif//SkDynamicAnnotations_DEFINED
|
24
gfx/skia/skia/include/core/SkFilterQuality.h
Normal file
24
gfx/skia/skia/include/core/SkFilterQuality.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFilterQuality_DEFINED
|
||||
#define SkFilterQuality_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Controls how much filtering to be done when scaling/transforming complex colors
|
||||
* e.g. images
|
||||
*/
|
||||
enum SkFilterQuality {
|
||||
kNone_SkFilterQuality, //!< fastest but lowest quality, typically nearest-neighbor
|
||||
kLow_SkFilterQuality, //!< typically bilerp
|
||||
kMedium_SkFilterQuality, //!< typically bilerp + mipmaps for down-scaling
|
||||
kHigh_SkFilterQuality //!< slowest but highest quality, typically bicubic or better
|
||||
};
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user