Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: cc/layer_impl.h

Issue 11264056: cc: Use gfx:: Geometry types for positions, bounds, and related things. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ScaleAsVector Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/layer.cc ('k') | cc/layer_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CCLayerImpl_h 5 #ifndef CCLayerImpl_h
6 #define CCLayerImpl_h 6 #define CCLayerImpl_h
7 7
8 #include "FloatRect.h"
9 #include "IntRect.h"
10 #include "Region.h" 8 #include "Region.h"
11 #include "base/logging.h" 9 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
13 #include "cc/input_handler.h" 11 #include "cc/input_handler.h"
14 #include "cc/layer_animation_controller.h" 12 #include "cc/layer_animation_controller.h"
15 #include "cc/render_pass.h" 13 #include "cc/render_pass.h"
16 #include "cc/render_surface_impl.h" 14 #include "cc/render_surface_impl.h"
17 #include "cc/resource_provider.h" 15 #include "cc/resource_provider.h"
18 #include "cc/scoped_ptr_vector.h" 16 #include "cc/scoped_ptr_vector.h"
19 #include "cc/shared_quad_state.h" 17 #include "cc/shared_quad_state.h"
20 #include "third_party/skia/include/core/SkColor.h" 18 #include "third_party/skia/include/core/SkColor.h"
19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/rect_f.h"
21 #include <public/WebFilterOperations.h> 21 #include <public/WebFilterOperations.h>
22 #include <public/WebTransformationMatrix.h> 22 #include <public/WebTransformationMatrix.h>
23 #include <string> 23 #include <string>
24 24
25 namespace cc { 25 namespace cc {
26 26
27 class LayerSorter; 27 class LayerSorter;
28 class LayerTreeHostImpl; 28 class LayerTreeHostImpl;
29 class QuadSink; 29 class QuadSink;
30 class Renderer; 30 class Renderer;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Returns true if this layer has content to draw. 88 // Returns true if this layer has content to draw.
89 void setDrawsContent(bool); 89 void setDrawsContent(bool);
90 bool drawsContent() const { return m_drawsContent; } 90 bool drawsContent() const { return m_drawsContent; }
91 91
92 bool forceRenderSurface() const { return m_forceRenderSurface; } 92 bool forceRenderSurface() const { return m_forceRenderSurface; }
93 void setForceRenderSurface(bool force) { m_forceRenderSurface = force; } 93 void setForceRenderSurface(bool force) { m_forceRenderSurface = force; }
94 94
95 // Returns true if any of the layer's descendants has content to draw. 95 // Returns true if any of the layer's descendants has content to draw.
96 virtual bool descendantDrawsContent(); 96 virtual bool descendantDrawsContent();
97 97
98 void setAnchorPoint(const FloatPoint&); 98 void setAnchorPoint(const gfx::PointF&);
99 const FloatPoint& anchorPoint() const { return m_anchorPoint; } 99 const gfx::PointF& anchorPoint() const { return m_anchorPoint; }
100 100
101 void setAnchorPointZ(float); 101 void setAnchorPointZ(float);
102 float anchorPointZ() const { return m_anchorPointZ; } 102 float anchorPointZ() const { return m_anchorPointZ; }
103 103
104 void setBackgroundColor(SkColor); 104 void setBackgroundColor(SkColor);
105 SkColor backgroundColor() const { return m_backgroundColor; } 105 SkColor backgroundColor() const { return m_backgroundColor; }
106 106
107 void setFilters(const WebKit::WebFilterOperations&); 107 void setFilters(const WebKit::WebFilterOperations&);
108 const WebKit::WebFilterOperations& filters() const { return m_filters; } 108 const WebKit::WebFilterOperations& filters() const { return m_filters; }
109 109
110 void setBackgroundFilters(const WebKit::WebFilterOperations&); 110 void setBackgroundFilters(const WebKit::WebFilterOperations&);
111 const WebKit::WebFilterOperations& backgroundFilters() const { return m_back groundFilters; } 111 const WebKit::WebFilterOperations& backgroundFilters() const { return m_back groundFilters; }
112 112
113 void setFilter(SkImageFilter*); 113 void setFilter(SkImageFilter*);
114 SkImageFilter* filter() const { return m_filter; } 114 SkImageFilter* filter() const { return m_filter; }
115 115
116 void setMasksToBounds(bool); 116 void setMasksToBounds(bool);
117 bool masksToBounds() const { return m_masksToBounds; } 117 bool masksToBounds() const { return m_masksToBounds; }
118 118
119 void setContentsOpaque(bool); 119 void setContentsOpaque(bool);
120 bool contentsOpaque() const { return m_contentsOpaque; } 120 bool contentsOpaque() const { return m_contentsOpaque; }
121 121
122 void setOpacity(float); 122 void setOpacity(float);
123 bool opacityIsAnimating() const; 123 bool opacityIsAnimating() const;
124 124
125 void setPosition(const FloatPoint&); 125 void setPosition(const gfx::PointF&);
126 const FloatPoint& position() const { return m_position; } 126 const gfx::PointF& position() const { return m_position; }
127 127
128 void setIsContainerForFixedPositionLayers(bool isContainerForFixedPositionLa yers) { m_isContainerForFixedPositionLayers = isContainerForFixedPositionLayers; } 128 void setIsContainerForFixedPositionLayers(bool isContainerForFixedPositionLa yers) { m_isContainerForFixedPositionLayers = isContainerForFixedPositionLayers; }
129 bool isContainerForFixedPositionLayers() const { return m_isContainerForFixe dPositionLayers; } 129 bool isContainerForFixedPositionLayers() const { return m_isContainerForFixe dPositionLayers; }
130 130
131 void setFixedToContainerLayer(bool fixedToContainerLayer = true) { m_fixedTo ContainerLayer = fixedToContainerLayer;} 131 void setFixedToContainerLayer(bool fixedToContainerLayer = true) { m_fixedTo ContainerLayer = fixedToContainerLayer;}
132 bool fixedToContainerLayer() const { return m_fixedToContainerLayer; } 132 bool fixedToContainerLayer() const { return m_fixedToContainerLayer; }
133 133
134 void setPreserves3D(bool); 134 void setPreserves3D(bool);
135 bool preserves3D() const { return m_preserves3D; } 135 bool preserves3D() const { return m_preserves3D; }
136 136
(...skipping 27 matching lines...) Expand all
164 bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; } 164 bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
165 void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityI sAnimating = drawOpacityIsAnimating; } 165 void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityI sAnimating = drawOpacityIsAnimating; }
166 166
167 LayerImpl* renderTarget() const { DCHECK(!m_renderTarget || m_renderTarget-> renderSurface()); return m_renderTarget; } 167 LayerImpl* renderTarget() const { DCHECK(!m_renderTarget || m_renderTarget-> renderSurface()); return m_renderTarget; }
168 void setRenderTarget(LayerImpl* target) { m_renderTarget = target; } 168 void setRenderTarget(LayerImpl* target) { m_renderTarget = target; }
169 169
170 // The client should be responsible for setting bounds, contentBounds and 170 // The client should be responsible for setting bounds, contentBounds and
171 // contentsScale to appropriate values. LayerImpl doesn't calculate any of 171 // contentsScale to appropriate values. LayerImpl doesn't calculate any of
172 // them from the other values. 172 // them from the other values.
173 173
174 void setBounds(const IntSize&); 174 void setBounds(const gfx::Size&);
175 const IntSize& bounds() const { return m_bounds; } 175 const gfx::Size& bounds() const { return m_bounds; }
176 176
177 // ContentBounds may be [0, 1) pixels larger than bounds * contentsScale. 177 // ContentBounds may be [0, 1) pixels larger than bounds * contentsScale.
178 // Don't calculate scale from it. Use contentsScale instead for accuracy. 178 // Don't calculate scale from it. Use contentsScale instead for accuracy.
179 void setContentBounds(const IntSize&); 179 void setContentBounds(const gfx::Size&);
180 IntSize contentBounds() const { return m_contentBounds; } 180 gfx::Size contentBounds() const { return m_contentBounds; }
181 181
182 float contentsScaleX() const { return m_contentsScaleX; } 182 float contentsScaleX() const { return m_contentsScaleX; }
183 float contentsScaleY() const { return m_contentsScaleY; } 183 float contentsScaleY() const { return m_contentsScaleY; }
184 void setContentsScale(float contentsScaleX, float contentsScaleY); 184 void setContentsScale(float contentsScaleX, float contentsScaleY);
185 185
186 const IntPoint& scrollPosition() const { return m_scrollPosition; } 186 const IntPoint& scrollPosition() const { return m_scrollPosition; }
187 void setScrollPosition(const IntPoint&); 187 void setScrollPosition(const IntPoint&);
188 188
189 const IntSize& maxScrollPosition() const {return m_maxScrollPosition; } 189 const IntSize& maxScrollPosition() const {return m_maxScrollPosition; }
190 void setMaxScrollPosition(const IntSize&); 190 void setMaxScrollPosition(const IntSize&);
(...skipping 20 matching lines...) Expand all
211 void setHaveWheelEventHandlers(bool haveWheelEventHandlers) { m_haveWheelEve ntHandlers = haveWheelEventHandlers; } 211 void setHaveWheelEventHandlers(bool haveWheelEventHandlers) { m_haveWheelEve ntHandlers = haveWheelEventHandlers; }
212 212
213 const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRe gion; } 213 const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRe gion; }
214 void setNonFastScrollableRegion(const Region& region) { m_nonFastScrollableR egion = region; } 214 void setNonFastScrollableRegion(const Region& region) { m_nonFastScrollableR egion = region; }
215 215
216 void setDrawCheckerboardForMissingTiles(bool checkerboard) { m_drawCheckerbo ardForMissingTiles = checkerboard; } 216 void setDrawCheckerboardForMissingTiles(bool checkerboard) { m_drawCheckerbo ardForMissingTiles = checkerboard; }
217 bool drawCheckerboardForMissingTiles() const; 217 bool drawCheckerboardForMissingTiles() const;
218 218
219 InputHandlerClient::ScrollStatus tryScroll(const IntPoint& viewportPoint, In putHandlerClient::ScrollInputType) const; 219 InputHandlerClient::ScrollStatus tryScroll(const IntPoint& viewportPoint, In putHandlerClient::ScrollInputType) const;
220 220
221 const IntRect& visibleContentRect() const { return m_visibleContentRect; } 221 const gfx::Rect& visibleContentRect() const { return m_visibleContentRect; }
222 void setVisibleContentRect(const IntRect& visibleContentRect) { m_visibleCon tentRect = visibleContentRect; } 222 void setVisibleContentRect(const gfx::Rect& visibleContentRect) { m_visibleC ontentRect = visibleContentRect; }
223 223
224 bool doubleSided() const { return m_doubleSided; } 224 bool doubleSided() const { return m_doubleSided; }
225 void setDoubleSided(bool); 225 void setDoubleSided(bool);
226 226
227 void setTransform(const WebKit::WebTransformationMatrix&); 227 void setTransform(const WebKit::WebTransformationMatrix&);
228 bool transformIsAnimating() const; 228 bool transformIsAnimating() const;
229 229
230 const WebKit::WebTransformationMatrix& drawTransform() const { return m_draw Transform; } 230 const WebKit::WebTransformationMatrix& drawTransform() const { return m_draw Transform; }
231 void setDrawTransform(const WebKit::WebTransformationMatrix& matrix) { m_dra wTransform = matrix; } 231 void setDrawTransform(const WebKit::WebTransformationMatrix& matrix) { m_dra wTransform = matrix; }
232 const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; } 232 const WebKit::WebTransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; }
233 void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; } 233 void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; }
234 234
235 bool drawTransformIsAnimating() const { return m_drawTransformIsAnimating; } 235 bool drawTransformIsAnimating() const { return m_drawTransformIsAnimating; }
236 void setDrawTransformIsAnimating(bool animating) { m_drawTransformIsAnimatin g = animating; } 236 void setDrawTransformIsAnimating(bool animating) { m_drawTransformIsAnimatin g = animating; }
237 bool screenSpaceTransformIsAnimating() const { return m_screenSpaceTransform IsAnimating; } 237 bool screenSpaceTransformIsAnimating() const { return m_screenSpaceTransform IsAnimating; }
238 void setScreenSpaceTransformIsAnimating(bool animating) { m_screenSpaceTrans formIsAnimating = animating; } 238 void setScreenSpaceTransformIsAnimating(bool animating) { m_screenSpaceTrans formIsAnimating = animating; }
239 239
240 const IntRect& drawableContentRect() const { return m_drawableContentRect; } 240 const gfx::Rect& drawableContentRect() const { return m_drawableContentRect; }
241 void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = r ect; } 241 void setDrawableContentRect(const gfx::Rect& rect) { m_drawableContentRect = rect; }
242 const FloatRect& updateRect() const { return m_updateRect; } 242 const gfx::RectF& updateRect() const { return m_updateRect; }
243 void setUpdateRect(const FloatRect& updateRect) { m_updateRect = updateRect; } 243 void setUpdateRect(const gfx::RectF& updateRect) { m_updateRect = updateRect ; }
244 244
245 std::string layerTreeAsText() const; 245 std::string layerTreeAsText() const;
246 246
247 void setStackingOrderChanged(bool); 247 void setStackingOrderChanged(bool);
248 248
249 bool layerPropertyChanged() const { return m_layerPropertyChanged || layerIs AlwaysDamaged(); } 249 bool layerPropertyChanged() const { return m_layerPropertyChanged || layerIs AlwaysDamaged(); }
250 bool layerSurfacePropertyChanged() const; 250 bool layerSurfacePropertyChanged() const;
251 251
252 void resetAllChangeTrackingForSubtree(); 252 void resetAllChangeTrackingForSubtree();
253 253
254 virtual bool layerIsAlwaysDamaged() const; 254 virtual bool layerIsAlwaysDamaged() const;
255 255
256 LayerAnimationController* layerAnimationController() { return m_layerAnimati onController.get(); } 256 LayerAnimationController* layerAnimationController() { return m_layerAnimati onController.get(); }
257 257
258 virtual Region visibleContentOpaqueRegion() const; 258 virtual Region visibleContentOpaqueRegion() const;
259 259
260 // Indicates that the context previously used to render this layer 260 // Indicates that the context previously used to render this layer
261 // was lost and that a new one has been created. Won't be called 261 // was lost and that a new one has been created. Won't be called
262 // until the new context has been created successfully. 262 // until the new context has been created successfully.
263 virtual void didLoseContext(); 263 virtual void didLoseContext();
264 264
265 ScrollbarAnimationController* scrollbarAnimationController() const { return m_scrollbarAnimationController.get(); } 265 ScrollbarAnimationController* scrollbarAnimationController() const { return m_scrollbarAnimationController.get(); }
266 266
267 ScrollbarLayerImpl* horizontalScrollbarLayer() const; 267 ScrollbarLayerImpl* horizontalScrollbarLayer() const;
268 void setHorizontalScrollbarLayer(ScrollbarLayerImpl*); 268 void setHorizontalScrollbarLayer(ScrollbarLayerImpl*);
269 269
270 ScrollbarLayerImpl* verticalScrollbarLayer() const; 270 ScrollbarLayerImpl* verticalScrollbarLayer() const;
271 void setVerticalScrollbarLayer(ScrollbarLayerImpl*); 271 void setVerticalScrollbarLayer(ScrollbarLayerImpl*);
272 272
273 IntRect layerRectToContentRect(const FloatRect& layerRect) const; 273 gfx::Rect layerRectToContentRect(const gfx::RectF& layerRect) const;
274 274
275 protected: 275 protected:
276 explicit LayerImpl(int); 276 explicit LayerImpl(int);
277 277
278 void appendDebugBorderQuad(QuadSink&, const SharedQuadState*, AppendQuadsDat a&) const; 278 void appendDebugBorderQuad(QuadSink&, const SharedQuadState*, AppendQuadsDat a&) const;
279 279
280 virtual void dumpLayerProperties(std::string*, int indent) const; 280 virtual void dumpLayerProperties(std::string*, int indent) const;
281 static std::string indentString(int indent); 281 static std::string indentString(int indent);
282 282
283 private: 283 private:
(...skipping 15 matching lines...) Expand all
299 ScopedPtrVector<LayerImpl> m_children; 299 ScopedPtrVector<LayerImpl> m_children;
300 // m_maskLayer can be temporarily stolen during tree sync, we need this ID t o confirm newly assigned layer is still the previous one 300 // m_maskLayer can be temporarily stolen during tree sync, we need this ID t o confirm newly assigned layer is still the previous one
301 int m_maskLayerId; 301 int m_maskLayerId;
302 scoped_ptr<LayerImpl> m_maskLayer; 302 scoped_ptr<LayerImpl> m_maskLayer;
303 int m_replicaLayerId; // ditto 303 int m_replicaLayerId; // ditto
304 scoped_ptr<LayerImpl> m_replicaLayer; 304 scoped_ptr<LayerImpl> m_replicaLayer;
305 int m_layerId; 305 int m_layerId;
306 LayerTreeHostImpl* m_layerTreeHostImpl; 306 LayerTreeHostImpl* m_layerTreeHostImpl;
307 307
308 // Properties synchronized from the associated Layer. 308 // Properties synchronized from the associated Layer.
309 FloatPoint m_anchorPoint; 309 gfx::PointF m_anchorPoint;
310 float m_anchorPointZ; 310 float m_anchorPointZ;
311 IntSize m_bounds; 311 gfx::Size m_bounds;
312 IntSize m_contentBounds; 312 gfx::Size m_contentBounds;
313 float m_contentsScaleX; 313 float m_contentsScaleX;
314 float m_contentsScaleY; 314 float m_contentsScaleY;
315 IntPoint m_scrollPosition; 315 IntPoint m_scrollPosition;
316 bool m_scrollable; 316 bool m_scrollable;
317 bool m_shouldScrollOnMainThread; 317 bool m_shouldScrollOnMainThread;
318 bool m_haveWheelEventHandlers; 318 bool m_haveWheelEventHandlers;
319 Region m_nonFastScrollableRegion; 319 Region m_nonFastScrollableRegion;
320 SkColor m_backgroundColor; 320 SkColor m_backgroundColor;
321 321
322 // Whether the "back" of this layer should draw. 322 // Whether the "back" of this layer should draw.
323 bool m_doubleSided; 323 bool m_doubleSided;
324 324
325 // Tracks if drawing-related properties have changed since last redraw. 325 // Tracks if drawing-related properties have changed since last redraw.
326 bool m_layerPropertyChanged; 326 bool m_layerPropertyChanged;
327 327
328 // Indicates that a property has changed on this layer that would not 328 // Indicates that a property has changed on this layer that would not
329 // affect the pixels on its target surface, but would require redrawing 329 // affect the pixels on its target surface, but would require redrawing
330 // but would require redrawing the targetSurface onto its ancestor targetSur face. 330 // but would require redrawing the targetSurface onto its ancestor targetSur face.
331 // For layers that do not own a surface this flag acts as m_layerPropertyCha nged. 331 // For layers that do not own a surface this flag acts as m_layerPropertyCha nged.
332 bool m_layerSurfacePropertyChanged; 332 bool m_layerSurfacePropertyChanged;
333 333
334 // Uses layer's content space. 334 // Uses layer's content space.
335 IntRect m_visibleContentRect; 335 gfx::Rect m_visibleContentRect;
336 bool m_masksToBounds; 336 bool m_masksToBounds;
337 bool m_contentsOpaque; 337 bool m_contentsOpaque;
338 float m_opacity; 338 float m_opacity;
339 FloatPoint m_position; 339 gfx::PointF m_position;
340 bool m_preserves3D; 340 bool m_preserves3D;
341 bool m_useParentBackfaceVisibility; 341 bool m_useParentBackfaceVisibility;
342 bool m_drawCheckerboardForMissingTiles; 342 bool m_drawCheckerboardForMissingTiles;
343 WebKit::WebTransformationMatrix m_sublayerTransform; 343 WebKit::WebTransformationMatrix m_sublayerTransform;
344 WebKit::WebTransformationMatrix m_transform; 344 WebKit::WebTransformationMatrix m_transform;
345 bool m_useLCDText; 345 bool m_useLCDText;
346 346
347 bool m_drawsContent; 347 bool m_drawsContent;
348 bool m_forceRenderSurface; 348 bool m_forceRenderSurface;
349 349
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 #ifndef NDEBUG 387 #ifndef NDEBUG
388 bool m_betweenWillDrawAndDidDraw; 388 bool m_betweenWillDrawAndDidDraw;
389 #endif 389 #endif
390 390
391 // Render surface associated with this layer. The layer and its descendants 391 // Render surface associated with this layer. The layer and its descendants
392 // will render to this surface. 392 // will render to this surface.
393 scoped_ptr<RenderSurfaceImpl> m_renderSurface; 393 scoped_ptr<RenderSurfaceImpl> m_renderSurface;
394 394
395 // Hierarchical bounding rect containing the layer and its descendants. 395 // Hierarchical bounding rect containing the layer and its descendants.
396 // Uses target surface's space. 396 // Uses target surface's space.
397 IntRect m_drawableContentRect; 397 gfx::Rect m_drawableContentRect;
398 398
399 // Rect indicating what was repainted/updated during update. 399 // Rect indicating what was repainted/updated during update.
400 // Note that plugin layers bypass this and leave it empty. 400 // Note that plugin layers bypass this and leave it empty.
401 // Uses layer's content space. 401 // Uses layer's content space.
402 FloatRect m_updateRect; 402 gfx::RectF m_updateRect;
403 403
404 // Manages animations for this layer. 404 // Manages animations for this layer.
405 scoped_ptr<LayerAnimationController> m_layerAnimationController; 405 scoped_ptr<LayerAnimationController> m_layerAnimationController;
406 406
407 // Manages scrollbars for this layer 407 // Manages scrollbars for this layer
408 scoped_ptr<ScrollbarAnimationController> m_scrollbarAnimationController; 408 scoped_ptr<ScrollbarAnimationController> m_scrollbarAnimationController;
409 }; 409 };
410 410
411 void sortLayers(std::vector<LayerImpl*>::iterator first, std::vector<LayerImpl*> ::iterator end, LayerSorter*); 411 void sortLayers(std::vector<LayerImpl*>::iterator first, std::vector<LayerImpl*> ::iterator end, LayerSorter*);
412 412
413 } 413 }
414 414
415 #endif // CCLayerImpl_h 415 #endif // CCLayerImpl_h
OLDNEW
« no previous file with comments | « cc/layer.cc ('k') | cc/layer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698