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