本文共 7167 字,大约阅读时间需要 23 分钟。
void SurfaceFlinger::computeVisibleRegions( const LayerVector& currentLayers, uint32_t layerStack, Region& outDirtyRegion, Region& outOpaqueRegion){ ATRACE_CALL(); Region aboveOpaqueLayers; Region aboveCoveredLayers; Region dirty; outDirtyRegion.clear(); size_t i = currentLayers.size(); while (i--) { const sp& layer = currentLayers[i]; // start with the whole surface at its current location const Layer::State& s(layer->drawingState()); // only consider the layers on the given layer stack if (s.layerStack != layerStack) continue; /* * opaqueRegion: area of a surface that is fully opaque. */ Region opaqueRegion; /* * visibleRegion: area of a surface that is visible on screen * and not fully transparent. This is essentially the layer's * footprint minus the opaque regions above it. * Areas covered by a translucent surface are considered visible. */ Region visibleRegion; /* * coveredRegion: area of a surface that is covered by all * visible regions above it (which includes the translucent areas). */ Region coveredRegion; /* * transparentRegion: area of a surface that is hinted to be completely * transparent. This is only used to tell when the layer has no visible * non-transparent regions and can be removed from the layer list. It * does not affect the visibleRegion of this layer or any layers * beneath it. The hint may not be correct if apps don't respect the * SurfaceView restrictions (which, sadly, some don't). */ Region transparentRegion; // handle hidden surfaces by setting the visible region to empty if (CC_LIKELY(layer->isVisible())) { const bool translucent = !layer->isOpaque(); Rect bounds(s.transform.transform(layer->computeBounds())); visibleRegion.set(bounds); if (!visibleRegion.isEmpty()) { // Remove the transparent area from the visible region if (translucent) { const Transform tr(s.transform); if (tr.transformed()) { if (tr.preserveRects()) { if (tr.preserveRects()) { // transform the transparent region transparentRegion = tr.transform(s.activeTransparentRegion); } else { // transformation too complex, can't do the // transparent region optimization. transparentRegion.clear(); } } else { transparentRegion = s.activeTransparentRegion; } } // compute the opaque region const int32_t layerOrientation = s.transform.getOrientation(); if (s.alpha==255 && !translucent && ((layerOrientation & Transform::ROT_INVALID) == false)) { // the opaque region is the layer's footprint opaqueRegion = visibleRegion; } } } // Clip the covered region to the visible region coveredRegion = aboveCoveredLayers.intersect(visibleRegion); // Update aboveCoveredLayers for next (lower) layer aboveCoveredLayers.orSelf(visibleRegion); // subtract the opaque region covered by the layers above us visibleRegion.subtractSelf(aboveOpaqueLayers); // compute this layer's dirty region if (layer->contentDirty) { // we need to invalidate the whole region dirty = visibleRegion; // as well, as the old visible region dirty.orSelf(layer->visibleRegion); layer->contentDirty = false; } else { /* compute the exposed region: * the exposed region consists of two components: * 1) what's VISIBLE now and was COVERED before * 2) what's EXPOSED now less what was EXPOSED before * * note that (1) is conservative, we start with the whole * visible region but only keep what used to be covered by * something -- which mean it may have been exposed. * * (2) handles areas that were not covered by anything but got * exposed because of a resize. */ const Region newExposed = visibleRegion - coveredRegion; const Region oldVisibleRegion = layer->visibleRegion; const Region oldCoveredRegion = layer->coveredRegion; const Region oldExposed = oldVisibleRegion - oldCoveredRegion; dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); } dirty.subtractSelf(aboveOpaqueLayers); // accumulate to the screen dirty region outDirtyRegion.orSelf(dirty); // Update aboveOpaqueLayers for next (lower) layer aboveOpaqueLayers.orSelf(opaqueRegion); // Store the visible region in screen space layer->setVisibleRegion(visibleRegion); layer->setCoveredRegion(coveredRegion); layer->setVisibleNonTransparentRegion( visibleRegion.subtract(transparentRegion)); } outOpaqueRegion = aboveOpaqueLayers;}
Region:
可以包含多个rect -》 mStorge;
opengl绘制的时候可以仅仅绘制这些独立的,甚至是隔开的区域;
mbounds分裂
最重要的函数: void Region::boolean_operation(int op, Region& dst, const Region& lhs, const Region& rhs, int dx, int dy){ SkRegion::Op sk_op; switch (op) { case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break; case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; } sk_dst.op(sk_lhs, sk_rhs, sk_op); //调用skia的函数 } 数据成员 Rect mBounds; VectormStorage; isEmpty Returns true if the rectangle is empty (left >= right or top >= bottom) mBounds inline bool isEmpty() const { return mBounds.isEmpty(); } inline bool isRect() const { return mStorage.isEmpty(); } inline Rect getBounds() const { return mBounds; } inline Rect bounds() const { return getBounds(); } Region::const_iterator Region::begin() const { return isRect() ? &mBounds : mStorage.array();}Region::const_iterator Region::end() const { if (isRect()) { if (isEmpty()) { return &mBounds; } else { return &mBounds + 1; } } else { return mStorage.array() + mStorage.size(); }}
转载地址:http://naomi.baihongyu.com/