OLD | NEW |
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 #include "cc/trees/layer_tree_host.h" | 5 #include "cc/trees/layer_tree_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
(...skipping 2909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2920 | 2920 |
2921 int io_surface_id_; | 2921 int io_surface_id_; |
2922 MockIOSurfaceWebGraphicsContext3D* mock_context_; | 2922 MockIOSurfaceWebGraphicsContext3D* mock_context_; |
2923 gfx::Size io_surface_size_; | 2923 gfx::Size io_surface_size_; |
2924 }; | 2924 }; |
2925 | 2925 |
2926 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 | 2926 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 |
2927 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | 2927 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( |
2928 LayerTreeHostTestIOSurfaceDrawing); | 2928 LayerTreeHostTestIOSurfaceDrawing); |
2929 | 2929 |
2930 class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest { | |
2931 protected: | |
2932 virtual void SetupTree() OVERRIDE { | |
2933 root = FakeContentLayer::Create(&client_); | |
2934 root->SetBounds(gfx::Size(20, 20)); | |
2935 | |
2936 child = FakeContentLayer::Create(&client_); | |
2937 child->SetBounds(gfx::Size(10, 10)); | |
2938 root->AddChild(child); | |
2939 | |
2940 layer_tree_host()->SetRootLayer(root); | |
2941 LayerTreeHostTest::SetupTree(); | |
2942 } | |
2943 | |
2944 virtual void BeginTest() OVERRIDE { | |
2945 PostSetNeedsCommitToMainThread(); | |
2946 } | |
2947 | |
2948 virtual void DidCommitAndDrawFrame() OVERRIDE { | |
2949 WaitForCallback(); | |
2950 } | |
2951 | |
2952 void WaitForCallback() { | |
2953 base::MessageLoop::current()->PostTask( | |
2954 FROM_HERE, | |
2955 base::Bind( | |
2956 &LayerTreeHostTestAsyncReadback::NextStep, | |
2957 base::Unretained(this))); | |
2958 } | |
2959 | |
2960 void NextStep() { | |
2961 int frame = layer_tree_host()->source_frame_number(); | |
2962 switch (frame) { | |
2963 case 1: | |
2964 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( | |
2965 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback, | |
2966 base::Unretained(this)))); | |
2967 EXPECT_EQ(0u, callbacks_.size()); | |
2968 break; | |
2969 case 2: | |
2970 if (callbacks_.size() < 1u) { | |
2971 WaitForCallback(); | |
2972 return; | |
2973 } | |
2974 EXPECT_EQ(1u, callbacks_.size()); | |
2975 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString()); | |
2976 | |
2977 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( | |
2978 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback, | |
2979 base::Unretained(this)))); | |
2980 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( | |
2981 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback, | |
2982 base::Unretained(this)))); | |
2983 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( | |
2984 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback, | |
2985 base::Unretained(this)))); | |
2986 EXPECT_EQ(1u, callbacks_.size()); | |
2987 break; | |
2988 case 3: | |
2989 if (callbacks_.size() < 4u) { | |
2990 WaitForCallback(); | |
2991 return; | |
2992 } | |
2993 EXPECT_EQ(4u, callbacks_.size()); | |
2994 // The child was copied to a bitmap and passed back twice. | |
2995 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString()); | |
2996 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString()); | |
2997 // The root was copied to a bitmap and passed back also. | |
2998 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString()); | |
2999 EndTest(); | |
3000 break; | |
3001 } | |
3002 } | |
3003 | |
3004 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3005 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3006 EXPECT_TRUE(result->HasBitmap()); | |
3007 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass(); | |
3008 EXPECT_EQ(result->size().ToString(), | |
3009 gfx::Size(bitmap->width(), bitmap->height()).ToString()); | |
3010 callbacks_.push_back(result->size()); | |
3011 } | |
3012 | |
3013 virtual void AfterTest() OVERRIDE { | |
3014 EXPECT_EQ(4u, callbacks_.size()); | |
3015 } | |
3016 | |
3017 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) | |
3018 OVERRIDE { | |
3019 scoped_ptr<FakeOutputSurface> output_surface; | |
3020 if (use_gl_renderer_) { | |
3021 output_surface = FakeOutputSurface::Create3d().Pass(); | |
3022 } else { | |
3023 output_surface = FakeOutputSurface::CreateSoftware( | |
3024 make_scoped_ptr(new SoftwareOutputDevice)).Pass(); | |
3025 } | |
3026 return output_surface.PassAs<OutputSurface>(); | |
3027 } | |
3028 | |
3029 bool use_gl_renderer_; | |
3030 std::vector<gfx::Size> callbacks_; | |
3031 FakeContentLayerClient client_; | |
3032 scoped_refptr<FakeContentLayer> root; | |
3033 scoped_refptr<FakeContentLayer> child; | |
3034 }; | |
3035 | |
3036 // Readback can't be done with a delegating renderer. | |
3037 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) { | |
3038 use_gl_renderer_ = true; | |
3039 RunTest(false, false, false); | |
3040 } | |
3041 | |
3042 TEST_F(LayerTreeHostTestAsyncReadback, | |
3043 GLRenderer_RunMultiThread_MainThreadPainting) { | |
3044 use_gl_renderer_ = true; | |
3045 RunTest(true, false, false); | |
3046 } | |
3047 | |
3048 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) { | |
3049 use_gl_renderer_ = false; | |
3050 RunTest(false, false, false); | |
3051 } | |
3052 | |
3053 TEST_F(LayerTreeHostTestAsyncReadback, | |
3054 SoftwareRenderer_RunMultiThread_MainThreadPainting) { | |
3055 use_gl_renderer_ = false; | |
3056 RunTest(true, false, false); | |
3057 } | |
3058 | |
3059 class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest { | |
3060 protected: | |
3061 virtual void SetupTree() OVERRIDE { | |
3062 root_ = FakeContentLayer::Create(&client_); | |
3063 root_->SetBounds(gfx::Size(20, 20)); | |
3064 | |
3065 main_destroyed_ = FakeContentLayer::Create(&client_); | |
3066 main_destroyed_->SetBounds(gfx::Size(15, 15)); | |
3067 root_->AddChild(main_destroyed_); | |
3068 | |
3069 impl_destroyed_ = FakeContentLayer::Create(&client_); | |
3070 impl_destroyed_->SetBounds(gfx::Size(10, 10)); | |
3071 root_->AddChild(impl_destroyed_); | |
3072 | |
3073 layer_tree_host()->SetRootLayer(root_); | |
3074 LayerTreeHostTest::SetupTree(); | |
3075 } | |
3076 | |
3077 virtual void BeginTest() OVERRIDE { | |
3078 callback_count_ = 0; | |
3079 PostSetNeedsCommitToMainThread(); | |
3080 } | |
3081 | |
3082 virtual void DidCommit() OVERRIDE { | |
3083 int frame = layer_tree_host()->source_frame_number(); | |
3084 switch (frame) { | |
3085 case 1: | |
3086 main_destroyed_->RequestCopyOfOutput( | |
3087 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3088 &LayerTreeHostTestAsyncReadbackLayerDestroyed:: | |
3089 CopyOutputCallback, | |
3090 base::Unretained(this)))); | |
3091 impl_destroyed_->RequestCopyOfOutput( | |
3092 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3093 &LayerTreeHostTestAsyncReadbackLayerDestroyed:: | |
3094 CopyOutputCallback, | |
3095 base::Unretained(this)))); | |
3096 EXPECT_EQ(0, callback_count_); | |
3097 | |
3098 // Destroy the main thread layer right away. | |
3099 main_destroyed_->RemoveFromParent(); | |
3100 main_destroyed_ = NULL; | |
3101 | |
3102 // Should callback with a NULL bitmap. | |
3103 EXPECT_EQ(1, callback_count_); | |
3104 | |
3105 // Prevent drawing so we can't make a copy of the impl_destroyed layer. | |
3106 layer_tree_host()->SetViewportSize(gfx::Size()); | |
3107 break; | |
3108 case 2: | |
3109 // Flush the message loops and make sure the callbacks run. | |
3110 layer_tree_host()->SetNeedsCommit(); | |
3111 break; | |
3112 case 3: | |
3113 // No drawing means no readback yet. | |
3114 EXPECT_EQ(1, callback_count_); | |
3115 | |
3116 // Destroy the impl thread layer. | |
3117 impl_destroyed_->RemoveFromParent(); | |
3118 impl_destroyed_ = NULL; | |
3119 | |
3120 // No callback yet because it's on the impl side. | |
3121 EXPECT_EQ(1, callback_count_); | |
3122 break; | |
3123 case 4: | |
3124 // Flush the message loops and make sure the callbacks run. | |
3125 layer_tree_host()->SetNeedsCommit(); | |
3126 break; | |
3127 case 5: | |
3128 // We should get another callback with a NULL bitmap. | |
3129 EXPECT_EQ(2, callback_count_); | |
3130 EndTest(); | |
3131 break; | |
3132 } | |
3133 } | |
3134 | |
3135 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3136 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3137 EXPECT_TRUE(result->IsEmpty()); | |
3138 ++callback_count_; | |
3139 } | |
3140 | |
3141 virtual void AfterTest() OVERRIDE {} | |
3142 | |
3143 int callback_count_; | |
3144 FakeContentLayerClient client_; | |
3145 scoped_refptr<FakeContentLayer> root_; | |
3146 scoped_refptr<FakeContentLayer> main_destroyed_; | |
3147 scoped_refptr<FakeContentLayer> impl_destroyed_; | |
3148 }; | |
3149 | |
3150 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed); | |
3151 | |
3152 class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest { | |
3153 protected: | |
3154 virtual void SetupTree() OVERRIDE { | |
3155 root_ = FakeContentLayer::Create(&client_); | |
3156 root_->SetBounds(gfx::Size(20, 20)); | |
3157 | |
3158 grand_parent_layer_ = FakeContentLayer::Create(&client_); | |
3159 grand_parent_layer_->SetBounds(gfx::Size(15, 15)); | |
3160 root_->AddChild(grand_parent_layer_); | |
3161 | |
3162 // parent_layer_ owns a render surface. | |
3163 parent_layer_ = FakeContentLayer::Create(&client_); | |
3164 parent_layer_->SetBounds(gfx::Size(15, 15)); | |
3165 parent_layer_->SetForceRenderSurface(true); | |
3166 grand_parent_layer_->AddChild(parent_layer_); | |
3167 | |
3168 copy_layer_ = FakeContentLayer::Create(&client_); | |
3169 copy_layer_->SetBounds(gfx::Size(10, 10)); | |
3170 parent_layer_->AddChild(copy_layer_); | |
3171 | |
3172 layer_tree_host()->SetRootLayer(root_); | |
3173 LayerTreeHostTest::SetupTree(); | |
3174 } | |
3175 | |
3176 void AddCopyRequest(Layer* layer) { | |
3177 layer->RequestCopyOfOutput( | |
3178 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3179 &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback, | |
3180 base::Unretained(this)))); | |
3181 } | |
3182 | |
3183 virtual void BeginTest() OVERRIDE { | |
3184 callback_count_ = 0; | |
3185 PostSetNeedsCommitToMainThread(); | |
3186 | |
3187 AddCopyRequest(copy_layer_.get()); | |
3188 } | |
3189 | |
3190 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3191 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3192 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString()); | |
3193 ++callback_count_; | |
3194 | |
3195 switch (callback_count_) { | |
3196 case 1: | |
3197 // Hide the copy request layer. | |
3198 grand_parent_layer_->SetHideLayerAndSubtree(false); | |
3199 parent_layer_->SetHideLayerAndSubtree(false); | |
3200 copy_layer_->SetHideLayerAndSubtree(true); | |
3201 AddCopyRequest(copy_layer_.get()); | |
3202 break; | |
3203 case 2: | |
3204 // Hide the copy request layer's parent only. | |
3205 grand_parent_layer_->SetHideLayerAndSubtree(false); | |
3206 parent_layer_->SetHideLayerAndSubtree(true); | |
3207 copy_layer_->SetHideLayerAndSubtree(false); | |
3208 AddCopyRequest(copy_layer_.get()); | |
3209 break; | |
3210 case 3: | |
3211 // Hide the copy request layer's grand parent only. | |
3212 grand_parent_layer_->SetHideLayerAndSubtree(true); | |
3213 parent_layer_->SetHideLayerAndSubtree(false); | |
3214 copy_layer_->SetHideLayerAndSubtree(false); | |
3215 AddCopyRequest(copy_layer_.get()); | |
3216 break; | |
3217 case 4: | |
3218 // Hide the copy request layer's parent and grandparent. | |
3219 grand_parent_layer_->SetHideLayerAndSubtree(true); | |
3220 parent_layer_->SetHideLayerAndSubtree(true); | |
3221 copy_layer_->SetHideLayerAndSubtree(false); | |
3222 AddCopyRequest(copy_layer_.get()); | |
3223 break; | |
3224 case 5: | |
3225 // Hide the copy request layer as well as its parent and grandparent. | |
3226 grand_parent_layer_->SetHideLayerAndSubtree(true); | |
3227 parent_layer_->SetHideLayerAndSubtree(true); | |
3228 copy_layer_->SetHideLayerAndSubtree(true); | |
3229 AddCopyRequest(copy_layer_.get()); | |
3230 break; | |
3231 case 6: | |
3232 EndTest(); | |
3233 break; | |
3234 } | |
3235 } | |
3236 | |
3237 virtual void AfterTest() OVERRIDE {} | |
3238 | |
3239 int callback_count_; | |
3240 FakeContentLayerClient client_; | |
3241 scoped_refptr<FakeContentLayer> root_; | |
3242 scoped_refptr<FakeContentLayer> grand_parent_layer_; | |
3243 scoped_refptr<FakeContentLayer> parent_layer_; | |
3244 scoped_refptr<FakeContentLayer> copy_layer_; | |
3245 }; | |
3246 | |
3247 // No output to copy for delegated renderers. | |
3248 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
3249 LayerTreeHostTestAsyncReadbackInHiddenSubtree); | |
3250 | |
3251 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest | |
3252 : public LayerTreeHostTest { | |
3253 protected: | |
3254 virtual void SetupTree() OVERRIDE { | |
3255 root_ = FakeContentLayer::Create(&client_); | |
3256 root_->SetBounds(gfx::Size(20, 20)); | |
3257 | |
3258 grand_parent_layer_ = FakeContentLayer::Create(&client_); | |
3259 grand_parent_layer_->SetBounds(gfx::Size(15, 15)); | |
3260 grand_parent_layer_->SetHideLayerAndSubtree(true); | |
3261 root_->AddChild(grand_parent_layer_); | |
3262 | |
3263 // parent_layer_ owns a render surface. | |
3264 parent_layer_ = FakeContentLayer::Create(&client_); | |
3265 parent_layer_->SetBounds(gfx::Size(15, 15)); | |
3266 parent_layer_->SetForceRenderSurface(true); | |
3267 grand_parent_layer_->AddChild(parent_layer_); | |
3268 | |
3269 copy_layer_ = FakeContentLayer::Create(&client_); | |
3270 copy_layer_->SetBounds(gfx::Size(10, 10)); | |
3271 parent_layer_->AddChild(copy_layer_); | |
3272 | |
3273 layer_tree_host()->SetRootLayer(root_); | |
3274 LayerTreeHostTest::SetupTree(); | |
3275 } | |
3276 | |
3277 virtual void BeginTest() OVERRIDE { | |
3278 did_draw_ = false; | |
3279 PostSetNeedsCommitToMainThread(); | |
3280 | |
3281 copy_layer_->RequestCopyOfOutput( | |
3282 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3283 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest:: | |
3284 CopyOutputCallback, | |
3285 base::Unretained(this)))); | |
3286 } | |
3287 | |
3288 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3289 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3290 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString()); | |
3291 EndTest(); | |
3292 } | |
3293 | |
3294 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { | |
3295 Renderer* renderer = host_impl->renderer(); | |
3296 | |
3297 LayerImpl* root = host_impl->active_tree()->root_layer(); | |
3298 LayerImpl* grand_parent = root->children()[0]; | |
3299 LayerImpl* parent = grand_parent->children()[0]; | |
3300 LayerImpl* copy_layer = parent->children()[0]; | |
3301 | |
3302 // |parent| owns a surface, but it was hidden and not part of the copy | |
3303 // request so it should not allocate any resource. | |
3304 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting( | |
3305 parent->render_surface()->RenderPassId())); | |
3306 | |
3307 // |copy_layer| should have been rendered to a texture since it was needed | |
3308 // for a copy request. | |
3309 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting( | |
3310 copy_layer->render_surface()->RenderPassId())); | |
3311 | |
3312 did_draw_ = true; | |
3313 } | |
3314 | |
3315 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); } | |
3316 | |
3317 FakeContentLayerClient client_; | |
3318 bool did_draw_; | |
3319 scoped_refptr<FakeContentLayer> root_; | |
3320 scoped_refptr<FakeContentLayer> grand_parent_layer_; | |
3321 scoped_refptr<FakeContentLayer> parent_layer_; | |
3322 scoped_refptr<FakeContentLayer> copy_layer_; | |
3323 }; | |
3324 | |
3325 // No output to copy for delegated renderers. | |
3326 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
3327 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest); | |
3328 | |
3329 class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest { | |
3330 protected: | |
3331 virtual void SetupTree() OVERRIDE { | |
3332 root_ = FakeContentLayer::Create(&client_); | |
3333 root_->SetBounds(gfx::Size(20, 20)); | |
3334 | |
3335 parent_layer_ = FakeContentLayer::Create(&client_); | |
3336 parent_layer_->SetBounds(gfx::Size(15, 15)); | |
3337 parent_layer_->SetMasksToBounds(true); | |
3338 root_->AddChild(parent_layer_); | |
3339 | |
3340 copy_layer_ = FakeContentLayer::Create(&client_); | |
3341 copy_layer_->SetPosition(gfx::Point(15, 15)); | |
3342 copy_layer_->SetBounds(gfx::Size(10, 10)); | |
3343 parent_layer_->AddChild(copy_layer_); | |
3344 | |
3345 layer_tree_host()->SetRootLayer(root_); | |
3346 LayerTreeHostTest::SetupTree(); | |
3347 } | |
3348 | |
3349 virtual void BeginTest() OVERRIDE { | |
3350 PostSetNeedsCommitToMainThread(); | |
3351 | |
3352 copy_layer_->RequestCopyOfOutput( | |
3353 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3354 &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback, | |
3355 base::Unretained(this)))); | |
3356 } | |
3357 | |
3358 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3359 // We should still get a callback with no output if the copy requested layer | |
3360 // was completely clipped away. | |
3361 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3362 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString()); | |
3363 EndTest(); | |
3364 } | |
3365 | |
3366 virtual void AfterTest() OVERRIDE {} | |
3367 | |
3368 FakeContentLayerClient client_; | |
3369 scoped_refptr<FakeContentLayer> root_; | |
3370 scoped_refptr<FakeContentLayer> parent_layer_; | |
3371 scoped_refptr<FakeContentLayer> copy_layer_; | |
3372 }; | |
3373 | |
3374 // No output to copy for delegated renderers. | |
3375 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
3376 LayerTreeHostTestAsyncReadbackClippedOut); | |
3377 | |
3378 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest { | |
3379 protected: | |
3380 virtual void SetupTree() OVERRIDE { | |
3381 root_ = FakeContentLayer::Create(&client_); | |
3382 root_->SetBounds(gfx::Size(20, 20)); | |
3383 | |
3384 copy_layer_ = FakeContentLayer::Create(&client_); | |
3385 copy_layer_->SetBounds(gfx::Size(10, 10)); | |
3386 root_->AddChild(copy_layer_); | |
3387 | |
3388 layer_tree_host()->SetRootLayer(root_); | |
3389 LayerTreeHostTest::SetupTree(); | |
3390 } | |
3391 | |
3392 void AddCopyRequest(Layer* layer) { | |
3393 layer->RequestCopyOfOutput( | |
3394 CopyOutputRequest::CreateBitmapRequest(base::Bind( | |
3395 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback, | |
3396 base::Unretained(this)))); | |
3397 } | |
3398 | |
3399 virtual void BeginTest() OVERRIDE { | |
3400 saw_copy_request_ = false; | |
3401 callback_count_ = 0; | |
3402 PostSetNeedsCommitToMainThread(); | |
3403 | |
3404 // Prevent drawing. | |
3405 layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); | |
3406 | |
3407 AddCopyRequest(copy_layer_.get()); | |
3408 } | |
3409 | |
3410 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { | |
3411 if (impl->active_tree()->source_frame_number() == 0) { | |
3412 LayerImpl* root = impl->active_tree()->root_layer(); | |
3413 EXPECT_TRUE(root->children()[0]->HasCopyRequest()); | |
3414 saw_copy_request_ = true; | |
3415 } | |
3416 } | |
3417 | |
3418 virtual void DidCommit() OVERRIDE { | |
3419 if (layer_tree_host()->source_frame_number() == 1) { | |
3420 // Allow drawing. | |
3421 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds())); | |
3422 | |
3423 AddCopyRequest(copy_layer_.get()); | |
3424 } | |
3425 } | |
3426 | |
3427 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3428 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3429 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString()); | |
3430 ++callback_count_; | |
3431 | |
3432 if (callback_count_ == 2) | |
3433 EndTest(); | |
3434 } | |
3435 | |
3436 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); } | |
3437 | |
3438 bool saw_copy_request_; | |
3439 int callback_count_; | |
3440 FakeContentLayerClient client_; | |
3441 scoped_refptr<FakeContentLayer> root_; | |
3442 scoped_refptr<FakeContentLayer> copy_layer_; | |
3443 }; | |
3444 | |
3445 // No output to copy for delegated renderers. | |
3446 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
3447 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw); | |
3448 | |
3449 class LayerTreeHostTestAsyncReadbackLostOutputSurface | |
3450 : public LayerTreeHostTest { | |
3451 protected: | |
3452 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) | |
3453 OVERRIDE { | |
3454 if (!first_context_provider_.get()) { | |
3455 first_context_provider_ = TestContextProvider::Create(); | |
3456 return FakeOutputSurface::Create3d(first_context_provider_) | |
3457 .PassAs<OutputSurface>(); | |
3458 } | |
3459 | |
3460 EXPECT_FALSE(second_context_provider_.get()); | |
3461 second_context_provider_ = TestContextProvider::Create(); | |
3462 return FakeOutputSurface::Create3d(second_context_provider_) | |
3463 .PassAs<OutputSurface>(); | |
3464 } | |
3465 | |
3466 virtual void SetupTree() OVERRIDE { | |
3467 root_ = FakeContentLayer::Create(&client_); | |
3468 root_->SetBounds(gfx::Size(20, 20)); | |
3469 | |
3470 copy_layer_ = FakeContentLayer::Create(&client_); | |
3471 copy_layer_->SetBounds(gfx::Size(10, 10)); | |
3472 root_->AddChild(copy_layer_); | |
3473 | |
3474 layer_tree_host()->SetRootLayer(root_); | |
3475 LayerTreeHostTest::SetupTree(); | |
3476 } | |
3477 | |
3478 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } | |
3479 | |
3480 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { | |
3481 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); | |
3482 EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString()); | |
3483 EXPECT_TRUE(result->HasTexture()); | |
3484 | |
3485 // Save the result for later. | |
3486 EXPECT_FALSE(result_); | |
3487 result_ = result.Pass(); | |
3488 | |
3489 // Post a commit to lose the output surface. | |
3490 layer_tree_host()->SetNeedsCommit(); | |
3491 } | |
3492 | |
3493 virtual void DidCommitAndDrawFrame() OVERRIDE { | |
3494 switch (layer_tree_host()->source_frame_number()) { | |
3495 case 1: | |
3496 // The layers have been pushed to the impl side. The layer textures have | |
3497 // been allocated. | |
3498 | |
3499 // Request a copy of the layer. This will use another texture. | |
3500 copy_layer_->RequestCopyOfOutput( | |
3501 CopyOutputRequest::CreateRequest(base::Bind( | |
3502 &LayerTreeHostTestAsyncReadbackLostOutputSurface:: | |
3503 CopyOutputCallback, | |
3504 base::Unretained(this)))); | |
3505 break; | |
3506 case 4: | |
3507 // With SingleThreadProxy it takes two commits to finally swap after a | |
3508 // context loss. | |
3509 case 5: | |
3510 // Now destroy the CopyOutputResult, releasing the texture inside back | |
3511 // to the compositor. | |
3512 EXPECT_TRUE(result_); | |
3513 result_.reset(); | |
3514 | |
3515 // Check that it is released. | |
3516 ImplThreadTaskRunner()->PostTask( | |
3517 FROM_HERE, | |
3518 base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface:: | |
3519 CheckNumTextures, | |
3520 base::Unretained(this), | |
3521 num_textures_after_loss_ - 1)); | |
3522 break; | |
3523 } | |
3524 } | |
3525 | |
3526 virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result) | |
3527 OVERRIDE { | |
3528 switch (impl->active_tree()->source_frame_number()) { | |
3529 case 0: | |
3530 // The layers have been drawn, so their textures have been allocated. | |
3531 EXPECT_FALSE(result_); | |
3532 num_textures_without_readback_ = | |
3533 first_context_provider_->TestContext3d()->NumTextures(); | |
3534 break; | |
3535 case 1: | |
3536 // We did a readback, so there will be a readback texture around now. | |
3537 EXPECT_LT(num_textures_without_readback_, | |
3538 first_context_provider_->TestContext3d()->NumTextures()); | |
3539 break; | |
3540 case 2: | |
3541 // The readback texture is collected. | |
3542 EXPECT_TRUE(result_); | |
3543 | |
3544 // Lose the output surface. | |
3545 first_context_provider_->TestContext3d()->loseContextCHROMIUM( | |
3546 GL_GUILTY_CONTEXT_RESET_ARB, | |
3547 GL_INNOCENT_CONTEXT_RESET_ARB); | |
3548 break; | |
3549 case 3: | |
3550 // With SingleThreadProxy it takes two commits to finally swap after a | |
3551 // context loss. | |
3552 case 4: | |
3553 // The output surface has been recreated. | |
3554 EXPECT_TRUE(second_context_provider_.get()); | |
3555 | |
3556 num_textures_after_loss_ = | |
3557 first_context_provider_->TestContext3d()->NumTextures(); | |
3558 break; | |
3559 } | |
3560 } | |
3561 | |
3562 void CheckNumTextures(size_t expected_num_textures) { | |
3563 EXPECT_EQ(expected_num_textures, | |
3564 first_context_provider_->TestContext3d()->NumTextures()); | |
3565 EndTest(); | |
3566 } | |
3567 | |
3568 virtual void AfterTest() OVERRIDE {} | |
3569 | |
3570 scoped_refptr<TestContextProvider> first_context_provider_; | |
3571 scoped_refptr<TestContextProvider> second_context_provider_; | |
3572 size_t num_textures_without_readback_; | |
3573 size_t num_textures_after_loss_; | |
3574 FakeContentLayerClient client_; | |
3575 scoped_refptr<FakeContentLayer> root_; | |
3576 scoped_refptr<FakeContentLayer> copy_layer_; | |
3577 scoped_ptr<CopyOutputResult> result_; | |
3578 }; | |
3579 | |
3580 // No output to copy for delegated renderers. | |
3581 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
3582 LayerTreeHostTestAsyncReadbackLostOutputSurface); | |
3583 | |
3584 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { | 2930 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { |
3585 public: | 2931 public: |
3586 virtual void BeginTest() OVERRIDE { | 2932 virtual void BeginTest() OVERRIDE { |
3587 frame_ = 0; | 2933 frame_ = 0; |
3588 PostSetNeedsCommitToMainThread(); | 2934 PostSetNeedsCommitToMainThread(); |
3589 } | 2935 } |
3590 | 2936 |
3591 // Round 1: commit + draw | 2937 // Round 1: commit + draw |
3592 // Round 2: commit only (no draw/swap) | 2938 // Round 2: commit only (no draw/swap) |
3593 // Round 3: draw only (no commit) | 2939 // Round 3: draw only (no commit) |
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5330 } | 4676 } |
5331 | 4677 |
5332 int commit_count_; | 4678 int commit_count_; |
5333 int commit_complete_count_; | 4679 int commit_complete_count_; |
5334 TestSwapPromiseResult swap_promise_result_[3]; | 4680 TestSwapPromiseResult swap_promise_result_[3]; |
5335 }; | 4681 }; |
5336 | 4682 |
5337 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); | 4683 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); |
5338 | 4684 |
5339 } // namespace cc | 4685 } // namespace cc |
OLD | NEW |