1 // GnashVaapiImage.cpp: GnashImage class used with VA API
2 //
3 //   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
4 //   Free Software Foundation, Inc.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 //
20 
21 #include <time.h>
22 
23 #include "log.h"
24 #include "GnashVaapiImage.h"
25 #include "VaapiSurface.h"
26 
27 namespace gnash {
28 
29 /// Get current value of microsecond timer
get_ticks_usec(void)30 static std::uint64_t get_ticks_usec(void)
31 {
32 #ifdef HAVE_CLOCK_GETTIME
33     struct timespec t;
34     clock_gettime(CLOCK_REALTIME, &t);
35     return (std::uint64_t)t.tv_sec * 1000000 + t.tv_nsec / 1000;
36 #else
37     struct timeval t;
38     gettimeofday(&t, NULL);
39     return (std::uint64_t)t.tv_sec * 1000000 + t.tv_usec;
40 #endif
41 }
42 
GnashVaapiImage(std::shared_ptr<VaapiSurface> surface,image::ImageType type)43 GnashVaapiImage::GnashVaapiImage(std::shared_ptr<VaapiSurface> surface,
44         image::ImageType type)
45     :
46     image::GnashImage(NULL, surface->width(), surface->height(), type,
47             image::GNASH_IMAGE_GPU),
48     _surface(surface),
49     _creation_time(get_ticks_usec())
50 {
51     log_debug(_("GnashVaapiImage::GnashVaapiImage(): surface 0x%08x, size %dx%d\n"),
52           _surface->get(), _width, _height);
53 }
54 
~GnashVaapiImage()55 GnashVaapiImage::~GnashVaapiImage()
56 {
57     log_debug(_("GnashVaapiImage::~GnashVaapiImage(): surface 0x%08x\n"),
58           _surface->get());
59 }
60 
update(std::shared_ptr<VaapiSurface> surface)61 void GnashVaapiImage::update(std::shared_ptr<VaapiSurface> surface)
62 {
63     _surface = surface;
64     _creation_time = get_ticks_usec();
65 }
66 
update(std::uint8_t * data)67 void GnashVaapiImage::update(std::uint8_t* data)
68 {
69     log_debug(_("GnashVaapi::update(): data %p\n"), data);
70 
71     // XXX: use vaPutImage()
72     _creation_time = get_ticks_usec();
73 }
74 
update(const image::GnashImage & from)75 void GnashVaapiImage::update(const image::GnashImage& from)
76 {
77     assert(stride() == from.stride());
78     assert(size() <= from.size());
79     assert(type() == from.type());
80 
81     switch (from.location()) {
82         case image::GNASH_IMAGE_CPU:
83             this->update(const_cast<std::uint8_t*>(from.begin()));
84             break;
85         case image::GNASH_IMAGE_GPU:
86             this->update(static_cast<const GnashVaapiImage&>(from).surface());
87             break;
88         default:
89             assert(0);
90             break;
91     }
92 }
93 
94 // Transfer (and convert) VA surface to CPU image data
transfer()95 bool GnashVaapiImage::transfer()
96 {
97     // NOTE: if VAAPI is used, we have a dedicated backend, so we
98     //       should not have to retrieve the VA surface underlying pixels.
99     //       Mark this usage scenario as a fatal error and fix the code
100     //       instead.
101     log_error(_("GnashVaapiImage: VA surface to SW pixels are not supported\n"));
102     assert(0);
103 
104     _data.reset();
105     return _data.get() != NULL;
106 }
107 
108 // Get access to the underlying data
109 image::GnashImage::iterator
begin()110 GnashVaapiImage::begin()
111 {
112     log_debug(_("GnashVaapiImage::data(): surface 0x%08x\n"), _surface->get());
113     log_debug(_("  -> %u usec from creation\n"),
114               (std::uint32_t)(get_ticks_usec() - _creation_time));
115 
116     if (!transfer()) {
117         return NULL;
118     }
119 
120     return _data.get();
121 }
122 
123 // Get read-only access to the underlying data
124 image::GnashImage::const_iterator
begin() const125 GnashVaapiImage::begin() const
126 {
127     log_debug(_("GnashVaapiImage::data() const: surface 0x%08x\n"),
128 	      _surface->get());
129     log_debug(_("  -> %u usec from creation\n"),
130           (std::uint32_t)(get_ticks_usec() - _creation_time));
131 
132     /* XXX: awful hack... */
133     if (!const_cast<GnashVaapiImage *>(this)->transfer()) {
134         return NULL;
135     }
136 
137     return _data.get();
138 }
139 
140 } // gnash namespace
141 
142 // local Variables:
143 // mode: C++
144 // indent-tabs-mode: nil
145 // End:
146