Beispiel #1
0
double __hxcpp_time_stamp()
{
#ifdef HX_WINDOWS
   static __int64 t0=0;
   static double period=0;
   __int64 now;

   if (QueryPerformanceCounter((LARGE_INTEGER*)&now))
   {
      if (t0==0)
      {
         t0 = now;
         __int64 freq;
         QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
         if (freq!=0)
            period = 1.0/freq;
      }
      if (period!=0)
         return (now-t0)*period;
   }

   return (double)clock() / ( (double)CLOCKS_PER_SEC);
#elif defined(HX_MACOS)
   static double time_scale = 0.0;
   if (time_scale==0.0)
   {
      mach_timebase_info_data_t info;
      mach_timebase_info(&info);
      time_scale = 1e-9 * (double)info.numer / info.denom;
   }
   double r =  mach_absolute_time() * time_scale;
   return mach_absolute_time() * time_scale;
#else
   #if defined(IPHONE) || defined(APPLETV)
      double t = CACurrentMediaTime();
   #elif defined(USE_GETTIMEOFDAY)
      struct timeval tv;
      if( gettimeofday(&tv,NULL) )
         return 0;
      double t =  ( tv.tv_sec + ((double)tv.tv_usec) / 1000000.0 );
   #elif defined(USE_CLOCK_GETTIME)
      struct timespec ts;
      clock_gettime(CLOCK_MONOTONIC, &ts);
      double t =  ( ts.tv_sec + ((double)ts.tv_nsec)*1e-9  );
   #else
      double t = (double)clock() * (1.0 / CLOCKS_PER_SEC);
   #endif
   if (t0==0) t0 = t;
   return t-t0;
#endif
}
        double now() {

            #if defined(HX_MACOS)

                static double time_scale = 0.0;

                if (time_scale == 0.0) {
                    mach_timebase_info_data_t info;
                    mach_timebase_info(&info);
                    time_scale = 1e-9 * (double)info.numer / info.denom;
                }

               return mach_absolute_time() * time_scale;

            #else

                #if defined(IPHONE)

                    double t = CACurrentMediaTime();

                #elif defined(GPH) || defined(HX_LINUX) || defined(EMSCRIPTEN)

                    struct timeval tv;

                    if( gettimeofday(&tv,NULL) ) {
                        return 0;
                    }

                    double t =  ( tv.tv_sec + ((double)tv.tv_usec) / 1000000.0 );

                #else

                    struct timespec ts;

                    clock_gettime(CLOCK_MONOTONIC, &ts);

                    double t =  ( ts.tv_sec + ((double)ts.tv_nsec)*1e-9  );

                #endif

                if (t0 == 0) {
                    t0 = t;
                }

                return t - t0;

            #endif

        } //now()
        static unsigned int Example_GetTicks()
        {
                #if defined(__APPLE__)
                        return (unsigned int)((CACurrentMediaTime()-s_ticksBaseTime)*1000.0);
                #elif defined(_WIN32)
                        LARGE_INTEGER current_time;
                        QueryPerformanceCounter(&current_time);
                        return (unsigned int)((current_time.QuadPart - s_ticksBaseTime.QuadPart) * 1000 * s_hiResSecondsPerTick);
                #else /* assuming POSIX */
                        /* clock_gettime is POSIX.1-2001 */
                        struct timespec current_time;
                        clock_gettime(CLOCK_MONOTONIC, &current_time);
                        return (unsigned int)((current_time.tv_sec - s_ticksBaseTime.tv_sec)*1000.0 + (current_time.tv_nsec - s_ticksBaseTime.tv_nsec) / 1000000);
						                #endif
        }
        static void Example_InitTime()
        {
                #if defined(__APPLE__)
                        s_ticksBaseTime = CACurrentMediaTime();
                
                #elif defined(_WIN32)
                        LARGE_INTEGER hi_res_ticks_per_second;
                        if(TRUE == QueryPerformanceFrequency(&hi_res_ticks_per_second))
                        {
                                QueryPerformanceCounter(&s_ticksBaseTime);
                                s_hiResSecondsPerTick = 1.0 / hi_res_ticks_per_second;
                        }
                        else
                        {
                                fprintf(stderr, "Windows error: High resolution clock failed. Audio will not work correctly.\n");
                        }
                #else
                        /* clock_gettime is POSIX.1-2001 */
                        clock_gettime(CLOCK_MONOTONIC, &s_ticksBaseTime);
                #endif

        }
void LegacyCACFLayerTreeHost::render(const Vector<CGRect>& windowDirtyRects)
{
    ASSERT(m_d3dDevice);

    if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
        // We can't reset the device right now. Try again soon.
        renderSoon();
        return;
    }

    CGRect bounds = this->bounds();

    // Give the renderer some space to use. This needs to be valid until the
    // wkCACFContextFinishUpdate() call below.
    char space[4096];
    if (!wkCACFContextBeginUpdate(m_context, space, sizeof(space), CACurrentMediaTime(), bounds, windowDirtyRects.data(), windowDirtyRects.size()))
        return;

    HRESULT err = S_OK;
    CFTimeInterval timeToNextRender = numeric_limits<CFTimeInterval>::infinity();

    do {
        // FIXME: don't need to clear dirty region if layer tree is opaque.

        WKCACFUpdateRectEnumerator* e = wkCACFContextCopyUpdateRectEnumerator(m_context);
        if (!e)
            break;

        Vector<D3DRECT, 64> rects;
        for (const CGRect* r = wkCACFUpdateRectEnumeratorNextRect(e); r; r = wkCACFUpdateRectEnumeratorNextRect(e)) {
            D3DRECT rect;
            rect.x1 = r->origin.x;
            rect.x2 = rect.x1 + r->size.width;
            rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
            rect.y2 = rect.y1 + r->size.height;

            rects.append(rect);
        }
        wkCACFUpdateRectEnumeratorRelease(e);

        timeToNextRender = wkCACFContextGetNextUpdateTime(m_context);

        if (rects.isEmpty())
            break;

        m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);

        m_d3dDevice->BeginScene();
        wkCACFContextRenderUpdate(m_context);
        m_d3dDevice->EndScene();

        err = m_d3dDevice->Present(0, 0, 0, 0);

        if (err == D3DERR_DEVICELOST) {
            wkCACFContextAddUpdateRect(m_context, bounds);
            if (!resetDevice(LostDevice)) {
                // We can't reset the device right now. Try again soon.
                renderSoon();
                return;
            }
        }
    } while (err == D3DERR_DEVICELOST);

    wkCACFContextFinishUpdate(m_context);

#ifndef NDEBUG
    if (m_printTree)
        rootLayer()->printTree();
#endif

    // If timeToNextRender is not infinity, it means animations are running, so queue up to render again
    if (timeToNextRender != numeric_limits<CFTimeInterval>::infinity())
        renderSoon();
}
Beispiel #6
0
void WKCACFLayerRenderer::render(const Vector<CGRect>& dirtyRects)
{
    ASSERT(m_d3dDevice);

    if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
        // We can't reset the device right now. Try again soon.
        renderSoon();
        return;
    }

    if (m_client && !m_client->shouldRender()) {
        renderSoon();
        return;
    }

    // Flush the root layer to the render tree.
    WKCACFContextFlusher::shared().flushAllContexts();

    CGRect bounds = this->bounds();

    CFTimeInterval t = CACurrentMediaTime();

    // Give the renderer some space to use. This needs to be valid until the
    // CARenderUpdateFinish() call below.
    char space[4096];
    CARenderUpdate* u = CARenderUpdateBegin(space, sizeof(space), t, 0, 0, &bounds);
    if (!u)
        return;

    CARenderContextLock(m_renderContext);
    CARenderUpdateAddContext(u, m_renderContext);
    CARenderContextUnlock(m_renderContext);

    for (size_t i = 0; i < dirtyRects.size(); ++i)
        CARenderUpdateAddRect(u, &dirtyRects[i]);

    HRESULT err = S_OK;
    do {
        CGSRegionObj rgn = CARenderUpdateCopyRegion(u);

        if (!rgn)
            break;

        // FIXME: don't need to clear dirty region if layer tree is opaque.

        Vector<D3DRECT, 64> rects;
        CGSRegionEnumeratorObj e = CGSRegionEnumerator(rgn);
        for (const CGRect* r = CGSNextRect(e); r; r = CGSNextRect(e)) {
            D3DRECT rect;
            rect.x1 = r->origin.x;
            rect.x2 = rect.x1 + r->size.width;
            rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
            rect.y2 = rect.y1 + r->size.height;

            rects.append(rect);
        }
        CGSReleaseRegionEnumerator(e);
        CGSReleaseRegion(rgn);

        if (rects.isEmpty())
            break;

        m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);

        m_d3dDevice->BeginScene();
        CARenderOGLRender(m_renderer, u);
        m_d3dDevice->EndScene();

        err = m_d3dDevice->Present(0, 0, 0, 0);

        if (err == D3DERR_DEVICELOST) {
            CARenderUpdateAddRect(u, &bounds);
            if (!resetDevice(LostDevice)) {
                // We can't reset the device right now. Try again soon.
                renderSoon();
                return;
            }
        }
    } while (err == D3DERR_DEVICELOST);

    CARenderUpdateFinish(u);

#ifndef NDEBUG
    if (m_printTree)
        m_rootLayer->printTree();
#endif
}
void WKCACFLayerRenderer::render(const Vector<CGRect>& windowDirtyRects)
{
    ASSERT(m_d3dDevice);

    if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
        // We can't reset the device right now. Try again soon.
        renderSoon();
        return;
    }

    if (m_client && !m_client->shouldRender()) {
        renderSoon();
        return;
    }

    // Sync the layer if needed
    if (m_syncLayerChanges) {
        m_client->syncCompositingState();
        m_syncLayerChanges = false;
    }

    // Flush the root layer to the render tree.
    wkCACFContextFlush(m_context);

    // All pending animations will have been started with the flush. Fire the animationStarted calls
    double currentTime = WTF::currentTime();
    double currentMediaTime = CACurrentMediaTime();
    double t = currentTime + wkCACFContextGetLastCommitTime(m_context) - currentMediaTime;
    ASSERT(t <= currentTime);

    HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
    for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it) {
        PlatformCALayerClient* owner = (*it)->owner();
        owner->platformCALayerAnimationStarted(t);
    }

    m_pendingAnimatedLayers.clear();

    CGRect bounds = this->bounds();

    // Give the renderer some space to use. This needs to be valid until the
    // wkCACFContextFinishUpdate() call below.
    char space[4096];
    if (!wkCACFContextBeginUpdate(m_context, space, sizeof(space), currentMediaTime, bounds, windowDirtyRects.data(), windowDirtyRects.size()))
        return;

    HRESULT err = S_OK;
    CFTimeInterval timeToNextRender = numeric_limits<CFTimeInterval>::infinity();

    do {
        // FIXME: don't need to clear dirty region if layer tree is opaque.

        WKCACFUpdateRectEnumerator* e = wkCACFContextCopyUpdateRectEnumerator(m_context);
        if (!e)
            break;

        Vector<D3DRECT, 64> rects;
        for (const CGRect* r = wkCACFUpdateRectEnumeratorNextRect(e); r; r = wkCACFUpdateRectEnumeratorNextRect(e)) {
            D3DRECT rect;
            rect.x1 = r->origin.x;
            rect.x2 = rect.x1 + r->size.width;
            rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
            rect.y2 = rect.y1 + r->size.height;

            rects.append(rect);
        }
        wkCACFUpdateRectEnumeratorRelease(e);

        timeToNextRender = wkCACFContextGetNextUpdateTime(m_context);

        if (rects.isEmpty())
            break;

        m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);

        m_d3dDevice->BeginScene();
        wkCACFContextRenderUpdate(m_context);
        m_d3dDevice->EndScene();

        err = m_d3dDevice->Present(0, 0, 0, 0);

        if (err == D3DERR_DEVICELOST) {
            wkCACFContextAddUpdateRect(m_context, bounds);
            if (!resetDevice(LostDevice)) {
                // We can't reset the device right now. Try again soon.
                renderSoon();
                return;
            }
        }
    } while (err == D3DERR_DEVICELOST);

    wkCACFContextFinishUpdate(m_context);

#ifndef NDEBUG
    if (m_printTree)
        m_rootLayer->printTree();
#endif

    // If timeToNextRender is not infinity, it means animations are running, so queue up to render again
    if (timeToNextRender != numeric_limits<CFTimeInterval>::infinity())
        renderSoon();
}
Beispiel #8
0
 double nowInSeconds() const {
   return CACurrentMediaTime();
 }