WebTransformationMatrix WebTransformOperations::apply() const { WebTransformationMatrix toReturn; for (size_t i = 0; i < m_private->operations.size(); ++i) toReturn.multiply(m_private->operations[i].matrix); return toReturn; }
WebTransformationMatrix WebTransformOperations::blend(const WebTransformOperations& from, double progress) const { WebTransformationMatrix toReturn; bool fromIdentity = from.isIdentity(); bool toIdentity = isIdentity(); if (fromIdentity && toIdentity) return toReturn; if (matchesTypes(from)) { size_t numOperations = max(fromIdentity ? 0 : from.m_private->operations.size(), toIdentity ? 0 : m_private->operations.size()); for (size_t i = 0; i < numOperations; ++i) { WebTransformationMatrix blended = blendTransformOperations( fromIdentity ? 0 : &from.m_private->operations[i], toIdentity ? 0 : &m_private->operations[i], progress); toReturn.multiply(blended); } } else { toReturn = apply(); WebTransformationMatrix fromTransform = from.apply(); toReturn.blend(fromTransform, progress); } return toReturn; }
WebTransformationMatrix CCLayerImpl::quadTransform() const { WebTransformationMatrix quadTransformation = drawTransform(); float offsetX = -0.5 * bounds().width(); float offsetY = -0.5 * bounds().height(); quadTransformation.translate(offsetX, offsetY); return quadTransformation; }
void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdater& updater) { TRACE_EVENT("CCLayerTreeHost::updateLayers", this, 0); if (!rootLayer->renderSurface()) rootLayer->createRenderSurface(); rootLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), deviceViewportSize())); IntRect rootClipRect(IntPoint(), deviceViewportSize()); rootLayer->setClipRect(rootClipRect); LayerList updateList; updateList.append(rootLayer); RenderSurfaceChromium* rootRenderSurface = rootLayer->renderSurface(); rootRenderSurface->clearLayerList(); { TRACE_EVENT("CCLayerTreeHost::updateLayers::calcDrawEtc", this, 0); WebTransformationMatrix identityMatrix; WebTransformationMatrix deviceScaleTransform; deviceScaleTransform.scale(m_deviceScaleFactor); CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, updateList, rootRenderSurface->layerList(), layerRendererCapabilities().maxTextureSize); FloatRect rootScissorRect(FloatPoint(0, 0), viewportSize()); CCLayerTreeHostCommon::calculateVisibleAndScissorRects(updateList, rootScissorRect); } // Reset partial texture update requests. m_partialTextureUpdateRequests = 0; reserveTextures(updateList); paintLayerContents(updateList, PaintVisible, updater); if (!m_triggerIdlePaints) return; size_t preferredLimitBytes = m_contentsTextureManager->preferredMemoryLimitBytes(); size_t maxLimitBytes = m_contentsTextureManager->maxMemoryLimitBytes(); m_contentsTextureManager->reduceMemoryToLimit(preferredLimitBytes); if (m_contentsTextureManager->currentMemoryUseBytes() >= preferredLimitBytes) return; // Idle painting should fail when we hit the preferred memory limit, // otherwise it will always push us towards the maximum limit. m_contentsTextureManager->setMaxMemoryLimitBytes(preferredLimitBytes); // The second (idle) paint will be a no-op in layers where painting already occured above. paintLayerContents(updateList, PaintIdle, updater); m_contentsTextureManager->setMaxMemoryLimitBytes(maxLimitBytes); for (size_t i = 0; i < updateList.size(); ++i) updateList[i]->clearRenderSurface(); }
static WebTransformationMatrix windowMatrix(int x, int y, int width, int height) { WebTransformationMatrix canvas; // Map to window position and scale up to pixel coordinates. canvas.translate3d(x, y, 0); canvas.scale3d(width, height, 0); // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1]) canvas.translate3d(0.5, 0.5, 0.5); canvas.scale3d(0.5, 0.5, 0.5); return canvas; }
void CCDamageTracker::extendDamageForLayer(CCLayerImpl* layer, FloatRect& targetDamageRect) { // There are two ways that a layer can damage a region of the target surface: // 1. Property change (e.g. opacity, position, transforms): // - the entire region of the layer itself damages the surface. // - the old layer region also damages the surface, because this region is now exposed. // - note that in many cases the old and new layer rects may overlap, which is fine. // // 2. Repaint/update: If a region of the layer that was repainted/updated, that // region damages the surface. // // Property changes take priority over update rects. // // This method is called when we want to consider how a layer contributes to its // targetRenderSurface, even if that layer owns the targetRenderSurface itself. // To consider how a layer's targetSurface contributes to the ancestorSurface, // extendDamageForRenderSurface() must be called instead. // Compute the layer's "originTransform" by translating the drawTransform. WebTransformationMatrix originTransform = layer->drawTransform(); originTransform.translate(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height()); bool layerIsNew = false; FloatRect oldLayerRect = removeRectFromCurrentFrame(layer->id(), layerIsNew); FloatRect layerRectInTargetSpace = CCMathUtil::mapClippedRect(originTransform, FloatRect(FloatPoint::zero(), layer->bounds())); saveRectForNextFrame(layer->id(), layerRectInTargetSpace); if (layerIsNew || layerNeedsToRedrawOntoItsTargetSurface(layer)) { // If a layer is new or has changed, then its entire layer rect affects the target surface. targetDamageRect.uniteIfNonZero(layerRectInTargetSpace); // The layer's old region is now exposed on the target surface, too. // Note oldLayerRect is already in target space. targetDamageRect.uniteIfNonZero(oldLayerRect); } else if (!layer->updateRect().isEmpty()) { // If the layer properties havent changed, then the the target surface is only // affected by the layer's update area, which could be empty. FloatRect updateRectInTargetSpace = CCMathUtil::mapClippedRect(originTransform, layer->updateRect()); targetDamageRect.uniteIfNonZero(updateRectInTargetSpace); } }
void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdater& updater) { TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers"); if (!rootLayer->renderSurface()) rootLayer->createRenderSurface(); rootLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), deviceViewportSize())); IntRect rootClipRect(IntPoint(), deviceViewportSize()); rootLayer->setClipRect(rootClipRect); LayerList updateList; updateList.append(rootLayer); RenderSurfaceChromium* rootRenderSurface = rootLayer->renderSurface(); rootRenderSurface->clearLayerList(); { TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers::calcDrawEtc"); WebTransformationMatrix identityMatrix; WebTransformationMatrix deviceScaleTransform; deviceScaleTransform.scale(m_deviceScaleFactor); CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, updateList, rootRenderSurface->layerList(), layerRendererCapabilities().maxTextureSize); FloatRect rootScissorRect(FloatPoint(0, 0), viewportSize()); CCLayerTreeHostCommon::calculateVisibleAndScissorRects(updateList, rootScissorRect); } // Reset partial texture update requests. m_partialTextureUpdateRequests = 0; prioritizeTextures(updateList); bool needMoreUpdates = paintLayerContents(updateList, updater); if (m_triggerIdleUpdates && needMoreUpdates) setNeedsCommit(); for (size_t i = 0; i < updateList.size(); ++i) updateList[i]->clearRenderSurface(); }
static WebTransformationMatrix orthoProjectionMatrix(float left, float right, float bottom, float top) { // Use the standard formula to map the clipping frustum to the cube from // [-1, -1, -1] to [1, 1, 1]. float deltaX = right - left; float deltaY = top - bottom; WebTransformationMatrix proj; if (!deltaX || !deltaY) return proj; proj.setM11(2.0f / deltaX); proj.setM41(-(right + left) / deltaX); proj.setM22(2.0f / deltaY); proj.setM42(-(top + bottom) / deltaY); // Z component of vertices is always set to zero as we don't use the depth buffer // while drawing. proj.setM33(0); return proj; }
bool isIdentity() const { return matrix.isIdentity(); }
static WebTransformationMatrix blendTransformOperations(const WebTransformOperation* from, const WebTransformOperation* to, double progress) { WebTransformationMatrix toReturn; if (isIdentity(from) && isIdentity(to)) return toReturn; WebTransformOperation::Type interpolationType = WebTransformOperation::WebTransformOperationIdentity; if (isIdentity(to)) interpolationType = from->type; else interpolationType = to->type; switch (interpolationType) { case WebTransformOperation::WebTransformOperationTranslate: { double fromX = isIdentity(from) ? 0 : from->translate.x; double fromY = isIdentity(from) ? 0 : from->translate.y; double fromZ = isIdentity(from) ? 0 : from->translate.z; double toX = isIdentity(to) ? 0 : to->translate.x; double toY = isIdentity(to) ? 0 : to->translate.y; double toZ = isIdentity(to) ? 0 : to->translate.z; toReturn.translate3d(blendDoubles(fromX, toX, progress), blendDoubles(fromY, toY, progress), blendDoubles(fromZ, toZ, progress)); break; } case WebTransformOperation::WebTransformOperationRotate: { double axisX = 0; double axisY = 0; double axisZ = 1; double fromAngle = 0; double toAngle = isIdentity(to) ? 0 : to->rotate.angle; if (shareSameAxis(from, to, axisX, axisY, axisZ, fromAngle)) toReturn.rotate3d(axisX, axisY, axisZ, blendDoubles(fromAngle, toAngle, progress)); else { WebTransformationMatrix toMatrix; if (!isIdentity(to)) toMatrix = to->matrix; WebTransformationMatrix fromMatrix; if (!isIdentity(from)) fromMatrix = from->matrix; toReturn = toMatrix; toReturn.blend(fromMatrix, progress); } break; } case WebTransformOperation::WebTransformOperationScale: { double fromX = isIdentity(from) ? 1 : from->scale.x; double fromY = isIdentity(from) ? 1 : from->scale.y; double fromZ = isIdentity(from) ? 1 : from->scale.z; double toX = isIdentity(to) ? 1 : to->scale.x; double toY = isIdentity(to) ? 1 : to->scale.y; double toZ = isIdentity(to) ? 1 : to->scale.z; toReturn.scale3d(blendDoubles(fromX, toX, progress), blendDoubles(fromY, toY, progress), blendDoubles(fromZ, toZ, progress)); break; } case WebTransformOperation::WebTransformOperationSkew: { double fromX = isIdentity(from) ? 0 : from->skew.x; double fromY = isIdentity(from) ? 0 : from->skew.y; double toX = isIdentity(to) ? 0 : to->skew.x; double toY = isIdentity(to) ? 0 : to->skew.y; toReturn.skewX(blendDoubles(fromX, toX, progress)); toReturn.skewY(blendDoubles(fromY, toY, progress)); break; } case WebTransformOperation::WebTransformOperationPerspective: { double fromPerspectiveDepth = isIdentity(from) ? numeric_limits<double>::max() : from->perspectiveDepth; double toPerspectiveDepth = isIdentity(to) ? numeric_limits<double>::max() : to->perspectiveDepth; toReturn.applyPerspective(blendDoubles(fromPerspectiveDepth, toPerspectiveDepth, progress)); break; } case WebTransformOperation::WebTransformOperationMatrix: { WebTransformationMatrix toMatrix; if (!isIdentity(to)) toMatrix = to->matrix; WebTransformationMatrix fromMatrix; if (!isIdentity(from)) fromMatrix = from->matrix; toReturn = toMatrix; toReturn.blend(fromMatrix, progress); break; } case WebTransformOperation::WebTransformOperationIdentity: // Do nothing. break; } return toReturn; }
WebTransformationMatrix WebTransformationMatrix::operator*(const WebTransformationMatrix& t) const { WebTransformationMatrix result = *this; result.multiply(t); return result; }
static void expectTranslateX(double translateX, const WebTransformationMatrix& matrix) { EXPECT_FLOAT_EQ(translateX, matrix.m41()); }