1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LayerAndroid_h 18 #define LayerAndroid_h 19 20 #if USE(ACCELERATED_COMPOSITING) 21 22 #include "FloatPoint.h" 23 #include "FloatPoint3D.h" 24 #include "FloatRect.h" 25 #include "GraphicsLayerClient.h" 26 #include "ImageTexture.h" 27 #include "Layer.h" 28 #include "RefPtr.h" 29 #include "SkBitmap.h" 30 #include "SkColor.h" 31 #include "SkRegion.h" 32 #include "SkStream.h" 33 #include "TransformationMatrix.h" 34 35 #include <wtf/HashMap.h> 36 37 #ifndef BZERO_DEFINED 38 #define BZERO_DEFINED 39 // http://www.opengroup.org/onlinepubs/000095399/functions/bzero.html 40 // For maximum portability, it is recommended to replace the function call to bzero() as follows: 41 #define bzero(b, len) (memset((b), '\0', (len)), (void) 0) 42 #endif 43 44 class SkBitmapRef; 45 class SkCanvas; 46 class SkMatrix; 47 class SkPicture; 48 49 namespace WebCore { 50 class LayerAndroid; 51 class ImageTexture; 52 } 53 54 namespace android { 55 class DrawExtra; 56 void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream); 57 WebCore::LayerAndroid* deserializeLayer(SkStream* stream); 58 void cleanupImageRefs(WebCore::LayerAndroid* layer); 59 } 60 61 using namespace android; 62 63 struct SkLength { 64 enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; 65 SkLengthType type; 66 SkScalar value; 67 SkLength() 68 { 69 type = Undefined; 70 value = 0; 71 } 72 bool defined() const 73 { 74 if (type == Undefined) 75 return false; 76 return true; 77 } 78 float calcFloatValue(float max) const 79 { 80 switch (type) { 81 case Percent: 82 return (max * value) / 100.0f; 83 case Fixed: 84 return value; 85 default: 86 return value; 87 } 88 } 89 }; 90 91 namespace WebCore { 92 93 class AndroidAnimation; 94 class BaseTileTexture; 95 class GLWebViewState; 96 class LayerAndroidFindState; 97 class RenderLayer; 98 class TiledPage; 99 class PaintedSurface; 100 101 class TexturesResult { 102 public: 103 TexturesResult() 104 : fixed(0) 105 , scrollable(0) 106 , clipped(0) 107 , full(0) 108 {} 109 110 int fixed; 111 int scrollable; 112 int clipped; 113 int full; 114 }; 115 116 class TEST_EXPORT LayerAndroid : public Layer { 117 public: 118 enum LayerType { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer }; 119 120 LayerAndroid(RenderLayer* owner); 121 LayerAndroid(const LayerAndroid& layer); 122 LayerAndroid(SkPicture*); 123 virtual ~LayerAndroid(); 124 125 virtual TiledPage* page() { return 0; } 126 127 void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; } 128 void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; } 129 FloatPoint translation() const; 130 // Returns a rect describing the bounds of the layer with the local 131 // transformation applied, expressed relative to the parent layer. 132 // FIXME: Currently we use only the translation component of the local 133 // transformation. 134 SkRect bounds() const; 135 IntRect clippedRect() const; 136 bool outsideViewport(); 137 138 IntRect unclippedArea(); 139 IntRect visibleArea(); 140 141 virtual bool needsTexture(); 142 void removeTexture(PaintedSurface*); 143 144 // Debug helper methods 145 int nbLayers(); 146 int nbTexturedLayers(); 147 void showLayer(int indent = 0); 148 149 void computeTexturesAmount(TexturesResult*); 150 151 float getScale() { return m_scale; } 152 153 // draw layer and its children via Z, pre-order traversal 154 virtual bool drawGL(); 155 bool drawChildrenGL(); 156 virtual bool drawCanvas(SkCanvas*); 157 bool drawChildrenCanvas(SkCanvas*); 158 159 // prepare layer and its children via reverse-Z, post-order traversal 160 void prepare(); 161 162 void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix, 163 const FloatRect& clip, float opacity, float scale); 164 void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } 165 float drawOpacity() { return m_drawOpacity; } 166 void setVisible(bool value) { m_visible = value; } 167 168 bool preserves3D() { return m_preserves3D; } 169 void setPreserves3D(bool value) { m_preserves3D = value; } 170 void setAnchorPointZ(float z) { m_anchorPointZ = z; } 171 float anchorPointZ() { return m_anchorPointZ; } 172 void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; } 173 const TransformationMatrix* drawTransform() const { return &m_drawTransform; } 174 void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; } 175 void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; } 176 const FloatRect& drawClip() { return m_clippingRect; } 177 178 void setFixedPosition(SkLength left, // CSS left property 179 SkLength top, // CSS top property 180 SkLength right, // CSS right property 181 SkLength bottom, // CSS bottom property 182 SkLength marginLeft, // CSS margin-left property 183 SkLength marginTop, // CSS margin-top property 184 SkLength marginRight, // CSS margin-right property 185 SkLength marginBottom, // CSS margin-bottom property 186 const IntPoint& renderLayerPos, // For undefined fixed position 187 SkRect viewRect) { // view rect, can be smaller than the layer's 188 m_fixedLeft = left; 189 m_fixedTop = top; 190 m_fixedRight = right; 191 m_fixedBottom = bottom; 192 m_fixedMarginLeft = marginLeft; 193 m_fixedMarginTop = marginTop; 194 m_fixedMarginRight = marginRight; 195 m_fixedMarginBottom = marginBottom; 196 m_fixedRect = viewRect; 197 m_isFixed = true; 198 m_renderLayerPos = renderLayerPos; 199 setShouldInheritFromRootTransform(true); 200 } 201 202 void setBackgroundColor(SkColor color); 203 void setMaskLayer(LayerAndroid*); 204 void setMasksToBounds(bool masksToBounds) 205 { 206 m_haveClip = masksToBounds; 207 } 208 bool masksToBounds() const { return m_haveClip; } 209 210 SkPicture* recordContext(); 211 212 void addAnimation(PassRefPtr<AndroidAnimation> anim); 213 void removeAnimationsForProperty(AnimatedPropertyID property); 214 void removeAnimationsForKeyframes(const String& name); 215 bool evaluateAnimations(); 216 bool evaluateAnimations(double time); 217 void initAnimations(); 218 bool hasAnimations() const; 219 void addDirtyArea(); 220 221 SkPicture* picture() const { return m_recordingPicture; } 222 223 // Given a rect in global space, subtracts from it the bounds of this layer 224 // and of all of its children. Returns the bounding rectangle of the result, 225 // in global space. 226 SkRect subtractLayers(const SkRect&) const; 227 228 void dumpLayers(FILE*, int indentLevel) const; 229 void dumpToLog() const; 230 231 /** Call this with the current viewport (scrolling, zoom) to update 232 the position of the fixed layers. 233 234 This call is recursive, so it should be called on the root of the 235 hierarchy. 236 */ 237 bool updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0); 238 239 /** Call this to update the position attribute, so that later calls 240 like bounds() will report the corrected position. 241 242 This call is recursive, so it should be called on the root of the 243 hierarchy. 244 */ 245 void updatePositions(); 246 247 void clipArea(SkTDArray<SkRect>* region) const; 248 const LayerAndroid* find(int* xPtr, int* yPtr, SkPicture* root) const; 249 const LayerAndroid* findById(int uniqueID) const 250 { 251 return const_cast<LayerAndroid*>(this)->findById(uniqueID); 252 } 253 LayerAndroid* findById(int uniqueID); 254 LayerAndroid* getChild(int index) const 255 { 256 return static_cast<LayerAndroid*>(this->INHERITED::getChild(index)); 257 } 258 int uniqueId() const { return m_uniqueId; } 259 bool isFixed() { return m_isFixed; } 260 261 /** This sets a content image -- calling it means we will use 262 the image directly when drawing the layer instead of using 263 the content painted by WebKit. 264 Images are handled in ImagesManager, as they can be shared 265 between layers. 266 */ 267 void setContentsImage(SkBitmapRef* img); 268 269 void bounds(SkRect*) const; 270 271 virtual LayerAndroid* copy() const { return new LayerAndroid(*this); } 272 273 void needsRepaint() { m_pictureUsed++; } 274 unsigned int pictureUsed() { return m_pictureUsed; } 275 276 void clearDirtyRegion(); 277 278 void contentDraw(SkCanvas*); 279 280 virtual bool isMedia() const { return false; } 281 virtual bool isVideo() const { return false; } 282 283 RenderLayer* owningLayer() const { return m_owningLayer; } 284 285 void setIsIframe(bool isIframe) { m_isIframe = isIframe; } 286 float zValue() const { return m_zValue; } 287 288 // ViewStateSerializer friends 289 friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream); 290 friend LayerAndroid* android::deserializeLayer(SkStream* stream); 291 friend void android::cleanupImageRefs(LayerAndroid* layer); 292 293 PaintedSurface* texture() { return m_texture; } 294 void obtainTextureForPainting(LayerAndroid* drawingLayer); 295 296 // Update layers using another tree. Only works for basic properties 297 // such as the position, the transform. Return true if anything more 298 // complex is needed. 299 bool updateWithTree(LayerAndroid*); 300 virtual bool updateWithLayer(LayerAndroid*); 301 302 int type() { return m_type; } 303 304 bool hasText() { return m_hasText; } 305 void checkTextPresence(); 306 307 void copyAnimationStartTimesRecursive(LayerAndroid* oldTree); 308 309 // rendering asset management 310 void swapTiles(); 311 void setIsDrawing(bool isDrawing); 312 void setIsPainting(Layer* drawingTree); 313 void mergeInvalsInto(Layer* replacementTree); 314 bool isReady(); 315 316 protected: 317 virtual void onDraw(SkCanvas*, SkScalar opacity); 318 319 TransformationMatrix m_drawTransform; 320 321 private: 322 class FindState; 323 #if DUMP_NAV_CACHE 324 friend class CachedLayer::Debug; // debugging access only 325 #endif 326 327 void copyAnimationStartTimes(LayerAndroid* oldLayer); 328 void findInner(FindState&) const; 329 bool prepareContext(bool force = false); 330 void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const; 331 332 // ------------------------------------------------------------------- 333 // Fields to be serialized 334 // ------------------------------------------------------------------- 335 336 bool m_haveClip; 337 bool m_isFixed; 338 bool m_backgroundColorSet; 339 bool m_isIframe; 340 341 SkLength m_fixedLeft; 342 SkLength m_fixedTop; 343 SkLength m_fixedRight; 344 SkLength m_fixedBottom; 345 SkLength m_fixedMarginLeft; 346 SkLength m_fixedMarginTop; 347 SkLength m_fixedMarginRight; 348 SkLength m_fixedMarginBottom; 349 SkRect m_fixedRect; 350 351 // When fixed element is undefined or auto, the render layer's position 352 // is needed for offset computation 353 IntPoint m_renderLayerPos; 354 355 bool m_backfaceVisibility; 356 bool m_visible; 357 358 SkColor m_backgroundColor; 359 360 bool m_preserves3D; 361 float m_anchorPointZ; 362 float m_drawOpacity; 363 364 // Note that m_recordingPicture and m_imageRef are mutually exclusive; 365 // m_recordingPicture is used when WebKit is asked to paint the layer's 366 // content, while m_imageRef contains an image that we directly 367 // composite, using the layer's dimensions as a destination rect. 368 // We do this as if the layer only contains an image, directly compositing 369 // it is a much faster method than using m_recordingPicture. 370 SkPicture* m_recordingPicture; 371 372 typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap; 373 KeyframesMap m_animations; 374 375 TransformationMatrix m_transform; 376 TransformationMatrix m_childrenTransform; 377 378 // ------------------------------------------------------------------- 379 // Fields that are not serialized (generated, cached, or non-serializable) 380 // ------------------------------------------------------------------- 381 382 SkPoint m_iframeOffset; 383 384 float m_zValue; 385 386 FloatRect m_clippingRect; 387 388 int m_uniqueId; 389 390 PaintedSurface* m_texture; 391 unsigned m_imageCRC; 392 393 unsigned int m_pictureUsed; 394 395 // used to signal the framework we need a repaint 396 bool m_hasRunningAnimations; 397 398 float m_scale; 399 400 // We try to not always compute the texture size, as this is quite heavy 401 static const double s_computeTextureDelay = 0.2; // 200 ms 402 double m_lastComputeTextureSize; 403 404 // This mutex serves two purposes. (1) It ensures that certain operations 405 // happen atomically and (2) it makes sure those operations are synchronized 406 // across all threads and cores. 407 android::Mutex m_atomicSync; 408 409 RenderLayer* m_owningLayer; 410 411 int m_type; 412 413 bool m_hasText; 414 415 typedef Layer INHERITED; 416 }; 417 418 } 419 420 #else 421 422 class SkPicture; 423 424 namespace WebCore { 425 426 class LayerAndroid { 427 public: 428 LayerAndroid(SkPicture* picture) : 429 m_recordingPicture(picture), // does not assign ownership 430 m_uniqueId(-1) 431 {} 432 SkPicture* picture() const { return m_recordingPicture; } 433 int uniqueId() const { return m_uniqueId; } 434 private: 435 SkPicture* m_recordingPicture; 436 int m_uniqueId; 437 }; 438 439 } 440 441 #endif // USE(ACCELERATED_COMPOSITING) 442 443 #endif // LayerAndroid_h 444